NestJS JWT Authentication
JSON Web Tokens let Nest APIs authenticate clients without server-side sessions. This lesson covers issuing tokens with @nestjs/jwt and verifying them with a Passport JWT strategy.
Issuing a JWT on Login JwtModule provides JwtService for signing and verifying tokens. After validating credentials, AuthService signs a payload (commonly sub user id and email) and returns the access token to the client.
@Injectable()
export class AuthService {
constructor(private jwtService: JwtService, private usersService: UsersService) {}
async login(user: User) {
const payload = { sub: user.id, email: user.email };
return { access_token: await this.jwtService.signAsync(payload) };
}
} Keep JWT payloads small and non-sensitive. Do not put passwords or secrets inside the token.
JWT Strategy Verification @Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(config: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: config.get<string>('JWT_SECRET'),
});
}
validate(payload: { sub: number; email: string }) {
return { userId: payload.sub, email: payload.email };
}
} ExtractJwt.fromAuthHeaderAsBearerToken() reads Authorization: Bearer .... secretOrKey must match the secret used when signing. validate() runs after signature/expiry checks succeed. Protect routes with @UseGuards(JwtAuthGuard). JWT Nest Cheatsheet Essential JWT pieces in a Nest app.
API Purpose JwtModule.register({ secret, signOptions }) Configure signing defaults jwtService.signAsync(payload) Create an access token passport-jwt Strategy Verify incoming bearer tokens AuthGuard('jwt') Protect a route with JWT expiresIn Limit token lifetime (e.g. 15m)
Configuring JwtModule From ConfigService Prefer JwtModule.registerAsync with ConfigService so secrets are not hard-coded in module files.
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
secret: config.get<string>('JWT_SECRET'),
signOptions: { expiresIn: '15m' },
}),
}) Where Clients Store Tokens SPAs often use memory or httpOnly cookies. Mobile apps store tokens in secure storage. Document your choice and mitigate XSS/CSRF accordingly.
Common Mistakes Using a weak or hard-coded JWT secret. Setting very long expiresIn without refresh tokens. Putting PII or permissions that change frequently inside a long-lived JWT. Forgetting ignoreExpiration: false and accepting expired tokens accidentally. Key Takeaways JwtService signs tokens; Passport JWT strategy verifies them on protected routes. Keep payloads minimal and secrets in configuration. Short-lived access tokens reduce risk if a token leaks. Use registerAsync to load secrets from ConfigService.
Pro Tip
Include a token version or jti claim if you need forced logout / revoke-all-sessions later without waiting for natural expiry.
NestJS Passport Go to next item