Skip to main content
Практика завдань

Як реалізувати автентифікацію з Passport у NestJS?

Аутентифікація в NestJS з Passport

NestJS безшовно інтегрується з Passport.js — найпопулярнішою бібліотекою аутентифікації для Node.js — через пакет @nestjs/passport.


Налаштування

bash
npm install @nestjs/passport passport passport-local passport-jwt npm install @nestjs/jwt npm install --save-dev @types/passport-local @types/passport-jwt

JWT Стратегія (Найпоширеніша для API)

1. Модуль Аутентифікації

typescript
@Module({ imports: [ PassportModule, JwtModule.register({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: '1h' }, }), UsersModule, ], providers: [AuthService, JwtStrategy, LocalStrategy], controllers: [AuthController], }) export class AuthModule {}

2. Локальна Стратегія (Увійти)

typescript
import { Strategy } from 'passport-local'; import { PassportStrategy } from '@nestjs/passport'; @Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private authService: AuthService) { super({ usernameField: 'email' }); } async validate(email: string, password: string): Promise<User> { const user = await this.authService.validateUser(email, password); if (!user) { throw new UnauthorizedException('Невірні облікові дані'); } return user; } }

3. JWT Стратегія (Захистити маршрути)

typescript
import { ExtractJwt, Strategy } from 'passport-jwt'; import { PassportStrategy } from '@nestjs/passport'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: process.env.JWT_SECRET, }); } async validate(payload: { sub: string; email: string }) { return { id: payload.sub, email: payload.email }; } }

4. Сервіс Аутентифікації

typescript
@Injectable() export class AuthService { constructor( private usersService: UsersService, private jwtService: JwtService, ) {} async validateUser(email: string, password: string) { const user = await this.usersService.findByEmail(email); if (user && await bcrypt.compare(password, user.password)) { const { password, ...result } = user; return result; } return null; } async login(user: User) { const payload = { sub: user.id, email: user.email }; return { access_token: this.jwtService.sign(payload), refresh_token: this.jwtService.sign(payload, { expiresIn: '7d' }), }; } async refreshToken(token: string) { const payload = this.jwtService.verify(token); const newPayload = { sub: payload.sub, email: payload.email }; return { access_token: this.jwtService.sign(newPayload), }; } }

5. Контролер Аутентифікації

typescript
@Controller('auth') export class AuthController { constructor(private authService: AuthService) {} @UseGuards(AuthGuard('local')) @Post('login') async login(@Request() req) { return this.authService.login(req.user); } @UseGuards(AuthGuard('jwt')) @Get('profile') getProfile(@Request() req) { return req.user; } @Post('refresh') async refresh(@Body('refresh_token') token: string) { return this.authService.refreshToken(token); } }

Глобальний JWT Гард

typescript
// jwt-auth.guard.ts @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { constructor(private reflector: Reflector) { super(); } canActivate(context: ExecutionContext) { const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [ context.getHandler(), context.getClass(), ]); if (isPublic) return true; return super.canActivate(context); } }
typescript
// app.module.ts — застосувати глобально @Module({ providers: [ { provide: APP_GUARD, useClass: JwtAuthGuard }, ], }) export class AppModule {}

Тепер використовуйте декоратор @Public(), щоб пропустити аутентифікацію:

typescript
@Controller('health') export class HealthController { @Public() @Get() check() { return { status: 'ok' }; } }

Підсумок Потоку

Увійти: POST /auth/login → LocalStrategy.validate() → AuthService.login() → JWT токен Запит: GET /api/protected Header: Authorization: Bearer <token> → JwtStrategy.validate() → req.user заповнений → Контролер

Найкраща практика: Використовуйте JWT для безстанної аутентифікації API. Реалізуйте токени оновлення з ротацією. Зберігайте токени в httpOnly куках для веб-додатків. Застосовуйте JwtAuthGuard глобально та використовуйте @Public() для відкритих маршрутів.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань