Search This Blog

Wednesday, January 15, 2025

How to post request in node js using http-proxy-middleware

 

Recently we faced issue to post the request via api server to another server to fix follow the 

code as below:

In node app.js use following to proxy post request to different server:

const postProxy = createProxyMiddleware({

target: 'http://localhost:4000/', // Target server
changeOrigin: true, // Change the origin header to the target URL
pathRewrite: {
'^/api': '', // Remove /api from the path when forwarding
},
on: {
proxyReq: fixRequestBody
},
onProxyReq: (proxyReq, req, res) => {
// Forward request body for POST requests
if (req.body && Object.keys(req.body).length > 0) {
const bodyData = JSON.stringify(req.body);
proxyReq.setHeader('Content-Type', 'application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
console.log(proxyReq);
}
},
logLevel: 'debug', // Enable detailed logs
});
// Proxy POST requests to /api/*
app.use(
'/api', postProxy
);


Cheers

Happy Coding !!

Tuesday, January 14, 2025

Microservice in Node js using API hub.

 To implement an API Hub design pattern with JWT authentication in your microservices architecture, the API Hub will serve as a central gateway to route requests to different microservices (User Service, Product Service). It ensures security, scalability, and simplified client interaction.


Architecture

  1. API Hub (Node.js):

    • Acts as a central gateway.
    • Verifies JWT tokens for authentication.
    • Routes requests to the appropriate microservice.
  2. Microservices (User & Product):

    • Handle specific domains (user and product).
    • Authenticate requests via JWT verification.
  3. JWT Authentication:

    • API Hub validates JWT.
    • Microservices assume the API Hub has already authenticated requests.
  4. Angular Frontend:

    • Sends requests with JWT tokens obtained after login.

Implementation

1. Create the API Hub

Install Dependencies
bash
mkdir api-hub cd api-hub npm init -y npm install express http-proxy-middleware jsonwebtoken body-parser cors dotenv
api-hub/index.js
require('dotenv').config(); const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const jwt = require('jsonwebtoken'); const bodyParser = require('body-parser'); const app = express(); const PORT = process.env.PORT || 3000; // Middleware app.use(bodyParser.json()); app.use(require('cors')()); // JWT Authentication Middleware const authenticateJWT = (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ message: 'Unauthorized' }); jwt.verify(token, process.env.JWT_SECRET, (err, user) => { if (err) return res.status(403).json({ message: 'Forbidden' }); req.user = user; // Attach user info to the request next(); }); }; // Route to Login (for generating JWT tokens) app.post('/login', (req, res) => { const { username, password } = req.body; // Mock authentication if (username === 'admin' && password === 'admin') { const token = jwt.sign({ username, role: 'admin' }, process.env.JWT_SECRET, { expiresIn: '1h' }); return res.json({ token }); } res.status(401).json({ message: 'Invalid credentials' }); }); // Proxy Middleware app.use( '/users', authenticateJWT, createProxyMiddleware({ target: 'http://localhost:3001', changeOrigin: true }) ); app.use( '/products', authenticateJWT, createProxyMiddleware({ target: 'http://localhost:3002', changeOrigin: true }) ); // Start Server app.listen(PORT, () => console.log(`API Hub running on http://localhost:${PORT}`));
.env
PORT=3000 JWT_SECRET=your_jwt_secret_key

2. Update User and Product Services

  • Add a middleware to verify JWT tokens.
  • JWT is validated at the API Hub, but additional verification can be done in services for security.
Example Middleware: authMiddleware.js

const jwt = require('jsonwebtoken'); module.exports = (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ message: 'Unauthorized' }); jwt.verify(token, process.env.JWT_SECRET, (err, user) => { if (err) return res.status(403).json({ message: 'Forbidden' }); req.user = user; next(); }); };

Add this middleware to all secure routes in both services:


const authMiddleware = require('./authMiddleware'); app.use(authMiddleware); // Apply globally

3. Angular Frontend Integration

Install Dependencies

npm install @auth0/angular-jwt
app.module.ts

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { JwtModule } from '@auth0/angular-jwt'; import { AppComponent } from './app.component'; export function tokenGetter() { return localStorage.getItem('access_token'); } @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, HttpClientModule, JwtModule.forRoot({ config: { tokenGetter, allowedDomains: ['localhost:3000'], // API Hub disallowedRoutes: ['http://localhost:3000/login'], }, }), ], bootstrap: [AppComponent], }) export class AppModule {}
user.service.ts (with JWT Authentication)

import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root', }) export class UserService { private baseUrl = 'http://localhost:3000/users'; constructor(private http: HttpClient) {} getUsers(): Observable<any> { return this.http.get(this.baseUrl); } login(credentials: any): Observable<any> { return this.http.post('http://localhost:3000/login', credentials); } }
app.component.ts

import { Component } from '@angular/core'; import { UserService } from './services/user.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { users: any[] = []; token: string | null = null; constructor(private userService: UserService) {} login() { this.userService.login({ username: 'admin', password: 'admin' }).subscribe( (response) => { this.token = response.token; localStorage.setItem('access_token', this.token); this.loadUsers(); }, (error) => console.error('Login failed', error) ); } loadUsers() { this.userService.getUsers().subscribe((data) => (this.users = data)); } }
app.component.html

<div> <button (click)="login()">Login</button> <ul> <li *ngFor="let user of users">{{ user.name }}</li> </ul> </div>

Key Features of the Setup

  1. API Hub:
    • Centralized authentication.
    • Routes requests to microservices securely.
  2. JWT Authentication:
    • Secure API communication.
    • Tokens managed by the frontend and verified at the backend.
  3. Scalable Design:
    • User and Product services are independently deployable.
    • API Hub is extendable to include more microservices.

This design ensures a robust, secure, and modular architecture suitable for modern microservices-based applications.


Cheers !! 

Monday, January 13, 2025

How to configure JWT interceptor in Angular

 


Define and export the jwtInterceptor function as below: (save in jwtInterceptor.ts)

import { HttpRequest, HttpHandlerFn } from '@angular/common/http';

import { inject } from '@angular/core';
import { AuthService } from '../services/auth.service'; // Replace with the actual path to your AuthService

export function jwtInterceptor(req: HttpRequest<any>, next: HttpHandlerFn) {
// Inject the AuthService to get the authentication token
const authToken = inject(AuthService).getToken();

// Clone the request and set the Authorization header
const newReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${authToken}`),
});

// Pass the cloned request to the next handler
return next(newReq);
}

Configurein AppConfig.js like below:


import { jwtInterceptor } from './interceptor/jwtInterceptor';// Import the function

export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideClientHydration(withEventReplay()),
provideHttpClient(withFetch(),withInterceptors([jwtInterceptor]),),
]
};

Note: Way to do int Angular 15+


That's it, you are set, Happy Conding !!

Cheers,
Kapil

Popular Posts