How to Integrate Fabrixly-IDS with Angular and Node.js
This guide explains how to secure an Angular frontend application and a Node.js / Express backend using Fabrixly-IDS OIDC authentication.
๐๏ธ Architecture Overview
- Frontend (Angular): Uses the industry-standard
angular-oauth2-oidcpackage to trigger PKCE redirects and store tokens in sessionStorage. - Identity Server (Fabrixly-IDS): Standard OIDC authentication portal.
- Backend (Node.js): Validates incoming tokens using JSON Web Key Sets (JWKS).
Part A: Frontend Setup (Angular)
1. Install Dependencies
npm install angular-oauth2-oidc --save
2. Configure Angular OAuth Module
Configure the authentication provider in your src/app/auth.config.ts configuration file:
import { AuthConfig } from 'angular-oauth2-oidc';
export const authCodeFlowConfig: AuthConfig = {
issuer: 'https://ids.fabrixly.com/oidc',
redirectUri: window.location.origin + '/index.html',
clientId: 'your-angular-client-id', // Registered in Admin Console
responseType: 'code',
scope: 'openid profile email offline_access',
showDebugInformation: true, // Set to false in production
useSilentRefresh: true,
};
Import and configure the module in src/app/app.config.ts:
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { OAuthModule } from 'angular-oauth2-oidc';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
importProvidersFrom(
HttpClientModule,
OAuthModule.forRoot({
resourceServer: {
allowedUrls: ['http://localhost:3000/api'], // Automatically attaches access token
sendAccessToken: true
}
})
)
]
};
3. Implement Auth Logic in Component
Create src/app/app.component.ts:
import { Component } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { authCodeFlowConfig } from './auth.config';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
template: `
<div style="padding: 40px;">
<h1>Angular + Fabrixly-IDS ๐ก๏ธ</h1>
<div *ngIf="!isAuthenticated()">
<button (click)="login()">Sign In with Fabrixly</button>
</div>
<div *ngIf="isAuthenticated()">
<p>Welcome, {{ getGivenName() }}!</p>
<button (click)="logout()">Log Out</button>
<hr />
<button (click)="callBackend()">Call Protected API</button>
<p *ngIf="backendResponse">Response: <strong>{{ backendResponse }}</strong></p>
</div>
</div>
`
})
export class AppComponent {
backendResponse = '';
constructor(private oauthService: OAuthService, private http: HttpClient) {
this.oauthService.configure(authCodeFlowConfig);
this.oauthService.loadDiscoveryDocumentAndTryLogin();
}
login() {
this.oauthService.initLoginFlow();
}
logout() {
this.oauthService.logOut();
}
isAuthenticated(): boolean {
return this.oauthService.hasValidAccessToken();
}
getGivenName(): string {
const claims: any = this.oauthService.getIdentityClaims();
return claims ? claims.name : 'User';
}
callBackend() {
this.http.get<any>('http://localhost:3000/api/protected').subscribe({
next: (res) => this.backendResponse = res.message,
error: (err) => this.backendResponse = 'Failed to load protected resource'
});
}
}
Part B: Backend Setup (Node.js + Express)
The backend authenticates incoming REST requests by parsing and checking the cryptographic signatures of JWT tokens issued by Fabrixly-IDS.
1. Install Dependencies
npm install express cors jsonwebtoken jwks-rsa
2. Implement JWT Validation Middleware
Create server.js:
const express = require('express');
const cors = require('cors');
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');
const app = express();
app.use(cors());
app.use(express.json());
const IDS_ISSUER = "https://ids.fabrixly.com/oidc";
const client = jwksClient({
jwksUri: `${IDS_ISSUER}/jwks`,
cache: true,
rateLimit: true
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
if (err) return callback(err);
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
}
const requireAuth = (req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return res.status(401).json({ error: "Missing authorization token" });
}
const token = authHeader.split(" ")[1];
jwt.verify(token, getKey, {
issuer: IDS_ISSUER,
algorithms: ["RS256"]
}, (err, decoded) => {
if (err) {
return res.status(403).json({ error: "Token validation failed: " + err.message });
}
req.user = decoded;
next();
});
};
app.get("/api/protected", requireAuth, (req, res) => {
res.json({
message: `Greetings from Node.js! Your user ID is ${req.user.sub}.`
});
});
app.listen(3000, () => console.log("Backend running on http://localhost:3000"));
Part C: Registering the Client in Admin Console
- Open your Fabrixly-IDS Admin Console -> navigate to Clients.
- Click Create Client:
- Client Name:
Angular SPA - Grant Types:
authorization_code,refresh_token - Response Types:
code - Redirect URIs:
http://localhost:4200/index.html(Angular local dev environment) - Token Endpoint Auth Method:
none(required for SPA clients)
- Client Name:
- Save the changes. You are ready to run and test!