Auth Service Integration Guide

This page exposes the public integration surface for the central auth service. It is intended for external applications that want to use the service seamlessly as an OAuth2 / OpenID Connect (OIDC) provider.

What this service exposes

The auth service acts as an OAuth2/OpenID Connect provider for registered client applications.

Public Endpoints

GET {AUTH_BASE_URL}/oidc/.well-known/openid-configuration
GET {AUTH_BASE_URL}/oauth/.well-known/openid-configuration
GET {AUTH_BASE_URL}/oidc/authorize
POST {AUTH_BASE_URL}/oidc/token
GET {AUTH_BASE_URL}/oidc/userinfo

Note: Replace {AUTH_BASE_URL} with the deployed auth service production instance URL, for example: https://auth.example.com.

Supported Auth Flow

This service mandates and supports the standard OAuth2 Authorization Code Flow with PKCE (Proof Key for Code Exchange).

Authorization Request

client_id redirect_uri response_type=code scope=openid email profile state code_challenge code_challenge_method=S256

Token Exchange Requirements

grant_type=authorization_code code client_id client_secret code_verifier redirect_uri

Note: The token endpoint also accepts Basic auth credentials via the Authorization header.

Redirect URI Validation rules

  • The absolute payload redirect_uri string must explicitly match a registered callback path for the client app.
  • localhost configurations are natively permitted to accelerate local machine testing workflows.
Implementation 01

Vanilla JavaScript Integration

Trigger safe window routing natively to initialize client hooks, then safely offload downstream validation exchange back onto a trusted server layer.

Client-side: Start Login Flow

auth.js
const authBaseUrl = 'https://auth.example.com';
const clientId = 'YOUR_CLIENT_ID';
const redirectUri = 'https://app.example.com/auth/callback';

const state = crypto.randomUUID();
const codeVerifier = crypto.randomUUID();
window.localStorage.setItem('pkce_code_verifier', codeVerifier);

async function sha256(value) {
  const bytes = new TextEncoder().encode(value);
  const digest = await crypto.subtle.digest('SHA-256', bytes);
  return btoa(String.fromCharCode(...new Uint8Array(digest)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

async function login() {
  const codeChallenge = await sha256(codeVerifier);
  const authUrl = new URL(`${authBaseUrl}/oidc/authorize`);
  authUrl.searchParams.set('response_type', 'code');
  authUrl.searchParams.set('client_id', clientId);
  authUrl.searchParams.set('redirect_uri', redirectUri);
  authUrl.searchParams.set('scope', 'openid email profile');
  authUrl.searchParams.set('state', state);
  authUrl.searchParams.set('code_challenge', codeChallenge);
  authUrl.searchParams.set('code_challenge_method', 'S256');

  window.location.href = authUrl.toString();
}

Backend: Secure Code Exchange Handler

server.js
import express from 'express';
import fetch from 'node-fetch';

const app = express();
app.use(express.json());

app.post('/auth/token', async (req, res) => {
  const { code, codeVerifier, redirectUri } = req.body;

  const tokenResponse = await fetch('https://auth.example.com/oidc/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'authorization_code',
      code,
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
      code_verifier: codeVerifier,
      redirect_uri: redirectUri,
    }),
  });

  const tokens = await tokenResponse.json();
  return res.json(tokens);
});

app.listen(3000);

Client-side: Post-Callback UI Router Processing

callback.js
const url = new URL(window.location.href);
const code = url.searchParams.get('code');
const state = url.searchParams.get('state');
const codeVerifier = window.localStorage.getItem('pkce_code_verifier');

fetch('/auth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    code,
    codeVerifier,
    redirectUri: 'https://app.example.com/auth/callback',
  }),
})
  .then((res) => res.json())
  .then((tokens) => {
    console.log('Tokens Captured Successfully', tokens);
  });
Security Constraint

Never embed or compromise your production client_secret configuration within public web-browser scripts. Always encapsulate authorization code completions entirely at server-side logic points.

Implementation 02

Next.js + NextAuth Architecture

Integrate NextAuth natively into modern applications by referencing discovery layouts dynamically.

Environment Configuration Matrix

NEXTAUTH_URL=https://app.example.com
AUTH_URL=https://auth.example.com
PRABISHA_CLIENT_ID=your-client-id
PRABISHA_CLIENT_SECRET=your-client-secret

Dynamic Provider Route Setup

[...nextauth].ts
import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.OpenIDConnect({
      id: 'prabisha',
      name: 'Prabisha Auth',
      issuer: process.env.AUTH_URL,
      clientId: process.env.PRABISHA_CLIENT_ID,
      clientSecret: process.env.PRABISHA_CLIENT_SECRET,
      wellKnown: `${process.env.AUTH_URL}/oidc/.well-known/openid-configuration`,
      authorization: {
        params: {
          scope: 'openid email profile',
          response_type: 'code',
        },
      },
      profile(profile) {
        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
        };
      },
    }),
  ],
  session: {
    strategy: 'jwt',
  },
});

NextAuth Parameter Reminders:

  • issuer: Standardizes internal base URL configuration mappings.
  • wellKnown: Leverages discovery profiles gracefully via target endpoints.
  • clientSecret: Encapsulated dynamically within localized server bounds.
Implementation 03

NestJS Controller Engine Setup

Explicitly control redirection boundaries and state parameters within server systems using `openid-client` libraries.

external-auth.controller.ts
import { Controller, Get, Query } from '@nestjs/common';
import { Issuer, generators } from 'openid-client';

@Controller('auth')
export class ExternalAuthController {
  private client: any;
  private codeVerifier: string;

  constructor() {
    this.initializeClient();
  }

  private async initializeClient() {
    const issuer = await Issuer.discover('https://auth.example.com/oidc/.well-known/openid-configuration');
    this.client = new issuer.Client({
      client_id: process.env.PRABISHA_CLIENT_ID,
      client_secret: process.env.PRABISHA_CLIENT_SECRET,
      redirect_uris: [process.env.PRABISHA_REDIRECT_URI],
      response_types: ['code'],
    });
  }

  @Get('login')
  async login() {
    this.codeVerifier = generators.codeVerifier();
    const codeChallenge = generators.codeChallenge(this.codeVerifier);

    const url = this.client.authorizationUrl({
      scope: 'openid email profile',
      response_type: 'code',
      code_challenge: codeChallenge,
      code_challenge_method: 'S256',
      state: generators.state(),
    });

    return { url };
  }

  @Get('callback')
  async callback(@Query('code') code: string, @Query('state') state: string) {
    const tokenSet = await this.client.callback(process.env.PRABISHA_REDIRECT_URI, { code, state }, { code_verifier: this.codeVerifier });
    return tokenSet;
  }
}
  • 01. Server Bounds Maintain code_verifier in memory until full callback execution returns.
  • 02. Direct Exchange Complete execution workflows targeting the structural /oidc/token paths directly.
  • 03. Payload Access Safely apply the generated tokens to build valid application sessions.

Recommended Integration Steps

STEP 01

Register Application

Obtain secure credentials (client_id and client_secret) from management portal.

STEP 02

Whitelist Callbacks

Configure permitted application destination redirect_uri pathways securely.

STEP 03

Validate Discovery

Verify metadata properties against standard provider discovery paths.

STEP 04

Initialize Redirects

Route workflows directly to /oidc/authorize alongside PKCE and state strings.

STEP 05

Backend Resolution

Capture dynamic parameter callbacks to clear final validation steps server-side.

STEP 06

Secure Token Sessions

Store returned security parameters inside high-security session targets.

Core Security Hardening Rules

  • No Secret Check-ins Never check your secret configuration parameters directly into standard Git source control systems.
  • Isolate Public Client Scripts Prevent secret parameters from emitting into customer-accessible web browser scripts.
  • Enforce Cross-Site Tokens Always require un-guessable state keys to protect application connections against injection or CSRF exploits.
  • Enforce Complete PKCE Proofs Require robust PKCE generation strategies to verify transactions originating from native browser setups.