Search This Blog

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 !! 

No comments:

Post a Comment

Thanks for your comment, will revert as soon as we read it.

Popular Posts