
Nestjs Expert
Implement NestJS JWT authentication, Passport strategies, and guards with public-route decorators in your API.
Overview
NestJS Expert is an agent skill for the Build phase that implements JWT Passport strategies, auth guards, and public route decorators in NestJS APIs.
Install
npx skills add https://github.com/jeffallan/claude-skills --skill nestjs-expertWhat is this skill?
- JwtStrategy with ExtractJwt from bearer header and validate() returning userId, email, and role
- JwtAuthGuard extending AuthGuard('jwt') with @Public() reflector bypass on handlers
- UnauthorizedException handling in handleRequest for invalid tokens
- ConfigService-driven JWT_SECRET for secretOrKey configuration
- TypeScript-ready NestJS Passport integration snippets
Adoption & trust: 3.1k installs on skills.sh; 9.7k GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
What problem does it solve?
You are adding JWT auth to a NestJS API and need correct Strategy, Guard, and @Public() patterns without trial-and-error.
Who is it for?
Solo builders creating or hardening NestJS REST APIs who want standard JWT guard behavior with optional public routes.
Skip if: Non-Nest stacks, greenfield projects choosing a different framework, or teams needing OAuth, refresh tokens, or full identity provider integration from this skill alone.
When should I use this skill?
When implementing or fixing NestJS JWT authentication, guards, or public routes in a TypeScript API.
What do I get? / Deliverables
You get working jwt.strategy.ts and jwt-auth.guard.ts patterns wired to ConfigService and bearer tokens ready to drop into your auth module.
- jwt.strategy.ts and jwt-auth.guard.ts implementations
- Public route decorator pattern for unauthenticated handlers
Recommended Skills
Journey fit
NestJS auth patterns are applied while you are building server-side APIs, which maps cleanly to the Build phase for backend work. Backend subphase fits because the skill focuses on JwtStrategy, JwtAuthGuard, ConfigService secrets, and route protection—not frontend or DevOps pipelines.
How it compares
Use this pattern library instead of generic Node JWT tutorials that do not cover Nest ExecutionContext, Reflector, and AuthGuard wiring.
Common Questions / FAQ
Who is nestjs-expert for?
NestJS Expert is for solo and indie developers building TypeScript APIs with NestJS who need JWT authentication and guard snippets aligned with Passport and ConfigModule.
When should I use nestjs-expert?
Use it during Build backend work when implementing login-protected routes, JwtStrategy validate payloads, or Public endpoints on new or existing Nest modules.
Is nestjs-expert safe to install?
It is documentation-style code guidance; review the Security Audits panel on this page and never commit real JWT_SECRET values from examples.
SKILL.md
READMESKILL.md - Nestjs Expert
# Authentication & Guards ## JWT Strategy ```typescript // jwt.strategy.ts import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { ConfigService } from '@nestjs/config'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor(private config: ConfigService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: config.get('JWT_SECRET'), }); } async validate(payload: { sub: string; email: string; role: string }) { return { userId: payload.sub, email: payload.email, role: payload.role }; } } ``` ## JWT Auth Guard ```typescript // jwt-auth.guard.ts import { Injectable, ExecutionContext, UnauthorizedException } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { Reflector } from '@nestjs/core'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { constructor(private reflector: Reflector) { super(); } canActivate(context: ExecutionContext) { const isPublic = this.reflector.get<boolean>('isPublic', context.getHandler()); if (isPublic) return true; return super.canActivate(context); } handleRequest(err: any, user: any) { if (err || !user) { throw err || new UnauthorizedException('Invalid token'); } return user; } } // Public decorator export const Public = () => SetMetadata('isPublic', true); ``` ## Roles Guard ```typescript // roles.decorator.ts export const Roles = (...roles: string[]) => SetMetadata('roles', roles); // roles.guard.ts @Injectable() export class RolesGuard implements CanActivate { constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const roles = this.reflector.getAllAndOverride<string[]>('roles', [ context.getHandler(), context.getClass(), ]); if (!roles) return true; const { user } = context.switchToHttp().getRequest(); return roles.includes(user.role); } } // Usage @UseGuards(JwtAuthGuard, RolesGuard) @Roles('admin') @Get('admin') adminEndpoint() {} ``` ## Auth Service ```typescript @Injectable() export class AuthService { constructor( private usersService: UsersService, private jwtService: JwtService, ) {} async validateUser(email: string, password: string): Promise<User | null> { const user = await this.usersService.findByEmail(email); if (user && await bcrypt.compare(password, user.password)) { return user; } return null; } async login(user: User) { const payload = { sub: user.id, email: user.email, role: user.role }; return { access_token: this.jwtService.sign(payload), refresh_token: this.jwtService.sign(payload, { expiresIn: '7d' }), }; } async register(dto: CreateUserDto) { const hashedPassword = await bcrypt.hash(dto.password, 10); return this.usersService.create({ ...dto, password: hashedPassword }); } } ``` ## Auth Module Setup ```typescript @Module({ imports: [ PassportModule.register({ defaultStrategy: 'jwt' }), JwtModule.registerAsync({ inject: [ConfigService], useFactory: (config: ConfigService) => ({ secret: config.get('JWT_SECRET'), signOptions: { expiresIn: '15m' }, }), }), UsersModule, ], providers: [AuthService, JwtStrategy], exports: [AuthService], }) export class AuthModule {} ``` ## Apply Guards Globally ```typescript // app.module.ts @Module({ providers: [ { provide: APP_GUARD, useClass: JwtAuthGuard }, { provide: APP_GUARD, useClass: RolesGuard }, ], }) export class AppModule {} ``` ## Quick Reference | Component | Purpose | |-----------|---------| | `JwtStrategy` | Validate JWT tokens | | `JwtAuthGuard` | Protect routes | | `RolesGuard` | Role-based access | | `@Public()` | Skip auth | | `@Roles('admin')` | Require role | | `@UseGuard