Add Auth Endpoints
Set up the required authentication endpoints to integrate your NestJS application with Wristband.
Implement the login and logout flows by using the Wristband SDK to create these four endpoints in your Nest.JS application:
- Login Endpoint
- Callback Endpoint
- Logout Endpoint
- Session Endpoint
Create Auth Controller
Create an AuthController and inject the WristbandExpressAuthService into its constructor. You will also need to import the WristbandAuthGuard.
// src/auth/auth.controller.ts
import { Controller, Get, Inject, Req, Res, UseGuards } from '@nestjs/common';
import { Request, Response } from 'express';
import { env } from 'node:process';
import { CallbackResult, WristbandExpressAuthService } from '@wristband/nestjs-auth';
import { WristbandAuthGuard } from '../guards/auth.guard';
// Auth Endpoints route prefix can be whatever you prefer
@Controller('api/auth')
export class AuthController {
constructor(
@Inject('WristbandAuth')
private readonly wristbandAuth: WristbandExpressAuthService,
) {}
// Auth endpoints to follow here...
}Login Endpoint
The Login Endpoint initiates login requests by constructing the authorization request and redirecting users to Wristband's Authorize Endpoint, which triggers the hosted login page to complete the authentication process.
The following code snippet demonstrates how to implement the Login Endpoint using the Wristband SDK:
// src/auth/auth.controller.ts (continued)
// ...
@Controller('api/auth')
export class AuthController {
// ...
// Login Endpoint - Route path can be whatever you prefer
@Get('login')
async login(@Req() req: Request, @Res() res: Response): Promise<void> {
// Call the Wristband login() method which will return a URL that should
// be used to redirect to Wristband's hosted login page.
const authorizeUrl = await this.wristbandAuth.login(req, res);
res.redirect(authorizeUrl);
}
}Callback Endpoint
After successful authentication, Wristband redirects the user to your application's Callback Endpoint. Calling wristbandAuth.callback() returns a CallbackResult object containing the user's tokens and claims.
To initialize the user's session, pass this callback data into session.fromCallback() to hydrate the session with the user's claims and tokens, then persist it by calling session.save().
The following code snippet demonstrates how to implement the Callback Endpoint using the Wristband SDK:
// src/auth/auth.controller.ts (continued)
// ...
@Controller('api/auth')
export class AuthController {
// ...
// Callback Endpoint - Route path can be whatever you prefer
@Get('callback')
async callback(@Req() req: Request, @Res() res: Response): Promise<void> {
// Call the Wristband callback() method to check if the user
// successfully authenticated. If the user did authenticate successfully,
// the user's tokens and claims can be retrieved from the CallbackResult.
const callbackResult: CallbackResult = await this.wristbandAuth.callback(req, res);
const { type, callbackData, reason, redirectUrl } = callbackResult;
if (type === 'redirect_required') {
// For some edge cases, such as if an invalid grant was passed to the token API,
// the SDK will return a redirect URL. Your code should redirect to it in order to
// restart the login flow.
res.redirect(redirectUrl);
return;
}
// Create a session for the authenticated user. If needed, custom fields can
// be stored in the session using the customFields parameter of the
// fromCallback() method.
req.session.fromCallback(callbackData);
await req.session.save();
// Once the Callback Endpoint has completed, we redirect to your app's
// default return URL (typically your app's home page) or to an explicit
// return URL, if one was specified in the original login request.
res.redirect(callbackData.returnUrl || '<replace_with_a_default_return_url>');
}
}Logout Endpoint
When a user logs out, you must clear all of their authenticated state. The Logout Endpoint accomplishes this by performing three tasks:
- Clear the application's local session state.
- Revoke any refresh tokens associated with the user.
- Redirect to Wristband's Logout Endpoint to terminate the user's Wristband auth session.
The following code snippet demonstrates how to implement the Logout Endpoint using the Wristband SDK:
// src/auth/auth.controller.ts (continued)
// ...
@Controller('api/auth')
export class AuthController {
// ...
// Logout Endpoint - Route path can be whatever you prefer
@Get('logout')
async logout(@Req() req: Request, @Res() res: Response): Promise<void> {
// Get all the necessary session data needed to perform the logout operation.
const { refreshToken, tenantName } = req.session;
// Clear your application's local session.
req.session.destroy();
// Call the Wristband logout() function and use the returned URL to redirect
// to Wristband's Logout Endpoint. This will delete Wristband's session
// that is associated to the authenticated user. When Wristband is done
// logging out the user it will redirect back to your application's login
// URL or to the explicitly provided redirect URL.
const logoutUrl = await this.wristbandAuth.logout(req, res, {
tenantName,
refreshToken
});
res.redirect(logoutUrl);
}
}Session Endpoint
The Session Endpoint verifies if an incoming request has a valid session and returns the corresponding session data. The frontend primarily uses this endpoint for two purposes:
- To allow the frontend to determine whether the user has a valid session.
- To provide the frontend with the user's session data for use within the browser.
The following code snippet demonstrates how to implement the Session Endpoint using the Wristband SDK:
Important: This endpoint must be protected with the auth guard.
// src/auth/auth.controller.ts (continued)
// ...
@Controller('api/auth')
export class AuthController {
//
// ...
//
// Session Endpoint - Route path can be whatever you prefer
@Get('session')
@UseGuards(WristbandAuthGuard) // The guard ensures an authenticated session.
getSessionResponse(@Req() req: Request, @Res() res: Response): void {
// Call the getSessionResponse() method to extract the user's
// session data and populate a SessionResponse. If needed, you can add
// additional data to the SessionResponse by using the metadata parameter
// of the getSessionResponse() method.
const sessionResponse = req.session.getSessionResponse();
res.header('Cache-Control', 'no-store');
res.header('Pragma', 'no-cache');
res.status(200).json(sessionResponse);
}
}Register The Auth Module
Now that the AuthController contains all your authentication endpoints, register it within a module to make it available to your application.
Create the Auth Module
Create an AuthModule that encapsulates the AuthController:
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
@Module({ controllers: [AuthController] })
export class AuthModule {}Add Auth Module to AppModule
Import the AuthModule into your AppModule to make the authentication routes available across your entire application:
// src/app.module.ts
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { env } from 'node:process';
import { WristbandExpressAuthModule } from '@wristband/nestjs-auth';
import {
WristbandExpressSessionMiddleware,
WristbandExpressSessionModule
} from '@wristband/nestjs-auth/session';
import { authConfig, sessionConfig, authGuardConfig } from './config/wristband.config';
// ADD: Import the AuthModule
import { AuthModule } from './auth/auth.module';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [authConfig, sessionConfig, authGuardConfig],
envFilePath: env.NODE_ENV === 'production' ? '' : '.env',
ignoreEnvFile: env.NODE_ENV === 'production',
}),
WristbandExpressAuthModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => configService.get('wristbandAuth'),
inject: [ConfigService],
}),
WristbandExpressSessionModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => configService.get('wristbandSession'),
inject: [ConfigService],
}),
// ADD: Add the AuthModule to the imports
AuthModule,
// ...any project-specific modules...
],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(WristbandExpressSessionMiddleware).forRoutes('{*splat}');
}
}Register Your Login Endpoint and Callback Endpoint With Wristband
Wristband needs to redirect to your application's Login and Callback Endpoints for several authentication flows. To configure these URLs, update the following two fields in the Wristband dashboard:
- Application Login URL
- Client Redirect URIs
In the sections below, we'll go over how to update these two fields.
Updating the Application Login URL
Follow these steps to update the Application Login URIs:
- From the Dashboard Home Page, select the appropriate application.

Figure 1: Select your Wristband application.
-
Navigate to the Application Settings page.
• Locate the Login URL field.
• Enter the URL of your application's Login Endpoint.
• Click Save when finished.

Figure 2: Configure the application Login URL.
Updating the Client Redirect URIs
Follow these steps to update the Client Redirect URIs:
-
Select OAuth2 Clients from the left navigation bar:
• Choose the client with the ID matching the client ID registered with the SDK.

Figure 3: Select the matching OAuth2 client.
-
On the Edit Client page:
• Navigate to the Redirect URIs section.
• Click the Add+ button.
• Enter the URL of your application's Callback Endpoint.
• Click Save when finished.

Figure 4: Add the Callback Endpoint as a Redirect URI.
Updated 11 days ago
What’s Next
Now that your authentication endpoints are set up and configured, let's verify that they're working correctly.