A standalone, reusable NestJS library for OAuth 2.0 / OIDC authentication with Authorization Code Flow.
npm install @sftech/nestjs-auth-backendA standalone, reusable NestJS library for OAuth 2.0 / OIDC authentication with Authorization Code Flow.
This library provides a complete authentication microservice that can be used as a central auth service for your microservices architecture.
- OAuth 2.0 / OIDC Authorization Code Flow with PKCE support
- Database-backed session management using TypeORM
- Session-based authentication with HTTP-only cookies
- Token management (Access Token, Refresh Token, ID Token)
- Single Sign-On (SSO) with provider logout support
- Clean Architecture (domain, application, infrastructure, presentation)
- REST API endpoints for authentication flows
``bash`
npm install @sftech/nestjs-auth-backend
`bash`
npm install @sftech/nestjs-core @sftech/nestjs-db
`typescript
import { Module } from '@nestjs/common';
import { NestjsAuthBackendModule } from '@sftech/nestjs-auth-backend';
@Module({
imports: [
NestjsAuthBackendModule.register({
// Module configuration options
}),
],
})
export class AppModule {}
`
The module uses configuration values from @sftech/nestjs-core configuration system. Add the following to your app.config.json:
`json`
{
"OAUTH_PROVIDER_URL": "https://your-oauth-provider.com/realms/your-realm",
"OAUTH_AUTHORIZATION_ENDPOINT": "https://your-oauth-provider.com/realms/your-realm/protocol/openid-connect/auth",
"OAUTH_TOKEN_ENDPOINT": "https://your-oauth-provider.com/realms/your-realm/protocol/openid-connect/token",
"OAUTH_USERINFO_ENDPOINT": "https://your-oauth-provider.com/realms/your-realm/protocol/openid-connect/userinfo",
"OAUTH_END_SESSION_ENDPOINT": "https://your-oauth-provider.com/realms/your-realm/protocol/openid-connect/logout",
"OAUTH_CLIENT_ID": "your-client-id",
"OAUTH_CLIENT_SECRET": "your-client-secret",
"OAUTH_REDIRECT_URL": "http://localhost:3000/api/auth/callback",
"OAUTH_FRONTEND_CALLBACK_URL": "http://localhost:4200/auth/callback",
"OAUTH_SCOPE": "openid profile email roles",
"OAUTH_SESSION_MODE": "single",
"OAUTH_SESSION_MAX_AGE": "3600000"
}
#### Configuration Parameters
| Parameter | Required | Description | Example |
|-----------|----------|-------------|---------|
| OAUTH_PROVIDER_URL | Yes | Base URL of OAuth provider | https://keycloak.example.com/realms/myrealm |OAUTH_AUTHORIZATION_ENDPOINT
| | Yes | OAuth authorization endpoint | https://keycloak.example.com/realms/myrealm/protocol/openid-connect/auth |OAUTH_TOKEN_ENDPOINT
| | Yes | OAuth token endpoint | https://keycloak.example.com/realms/myrealm/protocol/openid-connect/token |OAUTH_USERINFO_ENDPOINT
| | Yes | OAuth userinfo endpoint | https://keycloak.example.com/realms/myrealm/protocol/openid-connect/userinfo |OAUTH_END_SESSION_ENDPOINT
| | No | OAuth logout endpoint (for SSO logout) | https://keycloak.example.com/realms/myrealm/protocol/openid-connect/logout |OAUTH_CLIENT_ID
| | Yes | OAuth client ID | my-app |OAUTH_CLIENT_SECRET
| | Yes | OAuth client secret | your-secret-here |OAUTH_REDIRECT_URL
| | Yes | OAuth callback URL (this service) | http://localhost:3000/api/auth/callback |OAUTH_FRONTEND_CALLBACK_URL
| | No | Frontend callback URL (after login) | http://localhost:4200/auth/callback |OAUTH_SCOPE
| | Yes | OAuth scopes to request | openid profile email roles |OAUTH_SESSION_MODE
| | No | Session mode: single or multi | single (default) |OAUTH_SESSION_MAX_AGE
| | No | Session max age in milliseconds | 3600000 (1 hour, default) |
Note: Session cookie name is fixed to oauth_session (not configurable).
For Keycloak, the endpoints follow this pattern:
`json`
{
"OAUTH_PROVIDER_URL": "https://your-keycloak.com/realms/your-realm",
"OAUTH_AUTHORIZATION_ENDPOINT": "https://your-keycloak.com/realms/your-realm/protocol/openid-connect/auth",
"OAUTH_TOKEN_ENDPOINT": "https://your-keycloak.com/realms/your-realm/protocol/openid-connect/token",
"OAUTH_USERINFO_ENDPOINT": "https://your-keycloak.com/realms/your-realm/protocol/openid-connect/userinfo",
"OAUTH_END_SESSION_ENDPOINT": "https://your-keycloak.com/realms/your-realm/protocol/openid-connect/logout"
}
The module provides the following REST endpoints under /api/auth:
Initiates OAuth login flow by redirecting to OAuth provider.
Query Parameters:
- redirect_url (optional): URL to redirect to after successful login
Response: 302 Redirect to OAuth provider
---
Handles OAuth callback after user authentication. Exchanges authorization code for tokens and creates session.
Query Parameters:
- code (required): Authorization code from OAuth providerstate
- (required): State parameter for CSRF validation
Response: 302 Redirect to frontend callback URL with session cookie
---
Returns current authentication status. Does not require authentication.
Response:
`json`
{
"authenticated": true,
"userId": "user-id",
"email": "user@example.com",
"name": "John Doe",
"roles": ["admin", "user"],
"expiresAt": "2024-12-31T23:59:59.000Z",
"timeRemaining": 3600000
}
---
Returns current user information from session. Requires authentication.
Response:
`json`
{
"sub": "user-id",
"email": "user@example.com",
"name": "John Doe",
"roles": ["admin", "user"],
"expiresAt": "2024-12-31T23:59:59.000Z",
"timeRemaining": 3600000
}
---
Refreshes access token using refresh token. Extends session lifetime. Requires authentication.
Response:
`json`
{
"message": "Tokens refreshed successfully",
"expiresAt": "2024-12-31T23:59:59.000Z",
"timeRemaining": 3600000
}
---
Ends user session by deleting from database and clearing cookie. If OAUTH_END_SESSION_ENDPOINT is configured, redirects to OAuth provider logout for SSO logout.
Response (without provider logout):
`json`
{
"message": "Logout successful"
}
Response (with provider logout):
302 Redirect to OAuth provider logout endpoint
---
Handles OAuth provider logout callback. After the OAuth provider completes logout, they redirect back to this endpoint, which then redirects to the frontend.
Response: 302 Redirect to frontend callback URL
1. Frontend calls GET /auth/loginGET /auth/callback?code=xxx&state=xxx
2. Backend generates PKCE challenge and redirects to OAuth provider
3. User authenticates at OAuth provider
4. OAuth provider redirects back to oauth_session
5. Backend exchanges code for tokens (with PKCE verifier)
6. Backend creates session in database
7. Backend sets cookie (HTTP-only, Secure, SameSite)
8. Backend redirects to frontend callback URL
9. Frontend stores cookie and is now authenticated
1. Frontend calls POST /auth/logoutoauth_session
2. Backend deletes session from database
3. Backend clears cookieOAUTH_END_SESSION_ENDPOINT
4. If configured:id_token_hint
- Backend redirects to OAuth provider logout with GET /auth/logout/callback
- OAuth provider clears SSO session
- OAuth provider redirects back to (backend)OAUTH_FRONTEND_CALLBACK_URL
- Backend redirects to (frontend)
5. Otherwise: Returns JSON success response
Other microservices can validate sessions by calling GET /auth/status with the session cookie.
See @sftech/nestjs-auth for client library to validate sessions from microservices.
Sessions are stored in the database using TypeORM. The session entity includes:
- sessionId: Unique session identifier (stored in cookie)userId
- : User ID from OAuth provideraccessToken
- : OAuth access tokenrefreshToken
- : OAuth refresh token (optional)idToken
- : OIDC ID token (used for provider logout)expiresAt
- : Session expiration timestampuserInfo
- : Cached user information (email, name, roles)
- Single mode (OAUTH_SESSION_MODE=single): Only one active session per user. New login invalidates previous session.OAUTH_SESSION_MODE=multi
- Multi mode (): Multiple concurrent sessions allowed per user.
This library follows Clean Architecture principles:
``
lib/
├── domain/ # Core business models and interfaces
│ ├── models/ # Session, UserInfo domain models
│ ├── repositories/ # Repository interfaces (ports)
│ └── oauth-options.interface.ts
├── application/ # Use cases and business logic
│ └── usecases/ # Login, Callback, Logout, Refresh, etc.
├── infrastructure/ # External concerns
│ ├── entities/ # TypeORM database entities
│ ├── repositories/ # Repository implementations
│ └── mappers/ # Domain ↔ Entity mapping
└── presentation/ # REST API layer
├── controllers/ # AuthController
├── dtos/ # Request/Response DTOs
└── guards/ # SessionGuard
`bash`
nx build nestjs-auth-backend
`bashBuild first
nx build nestjs-auth-backend
MIT