diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 34ab9da..b3eb1bb 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -1,6 +1,8 @@ -import { Controller, Post, UseGuards, Request } from '@nestjs/common'; +import { Controller, Post, UseGuards, Request, Get } from '@nestjs/common'; import { LocalAuthGuard } from './local-auth.guard'; import { AuthService } from './auth.service'; +import { JwtAuthGuard } from './jwt-auth.guard'; +import {Public} from "./public.decorator"; @Controller({ path: 'auth', @@ -9,9 +11,16 @@ import { AuthService } from './auth.service'; export class AuthController { constructor(private authService: AuthService) {} + @Public() @UseGuards(LocalAuthGuard) @Post('login') async login(@Request() req) { return this.authService.login(req.user); } + + @UseGuards(JwtAuthGuard) + @Get('profile') + getProfile(@Request() req) { + return req.user; + } } diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 5df33e9..4ffd567 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -6,11 +6,15 @@ import { LocalStrategy } from './local.strategy'; import { AuthController } from './auth.controller'; import { JwtModule } from '@nestjs/jwt'; import { ConfigModule, ConfigService } from '@nestjs/config'; +import { JwtStrategy } from './jwt.strategy'; +import { APP_GUARD } from '@nestjs/core'; +import { JwtAuthGuard } from './jwt-auth.guard'; @Module({ imports: [ UsersModule, PassportModule, + ConfigModule, JwtModule.registerAsync({ imports: [ConfigModule], inject: [ConfigService], @@ -22,7 +26,16 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; }, }), ], - providers: [AuthService, LocalStrategy], + providers: [ + AuthService, + LocalStrategy, + JwtStrategy, + { + provide: APP_GUARD, + useClass: JwtAuthGuard, + }, + ], controllers: [AuthController], + exports: [AuthService], }) export class AuthModule {} diff --git a/src/auth/jwt-auth.guard.ts b/src/auth/jwt-auth.guard.ts new file mode 100644 index 0000000..9388eae --- /dev/null +++ b/src/auth/jwt-auth.guard.ts @@ -0,0 +1,24 @@ +import { ExecutionContext, Injectable } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { Reflector } from '@nestjs/core'; +import { IS_PUBLIC_KEY } from './public.decorator'; + +@Injectable() +export class JwtAuthGuard extends AuthGuard('jwt') { + constructor(private reflector: Reflector) { + super(); + } + + canActivate(context: ExecutionContext) { + const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ + context.getHandler(), + context.getClass(), + ]); + + if (isPublic) { + return true; + } + + return super.canActivate(context); + } +} diff --git a/src/auth/jwt.strategy.ts b/src/auth/jwt.strategy.ts new file mode 100644 index 0000000..08eccd1 --- /dev/null +++ b/src/auth/jwt.strategy.ts @@ -0,0 +1,19 @@ +import { ExtractJwt, Strategy } from 'passport-jwt'; +import { PassportStrategy } from '@nestjs/passport'; +import { Injectable } from '@nestjs/common'; +import {ConfigService} from "@nestjs/config"; + +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + constructor(configService: ConfigService) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: false, + secretOrKey: configService.get('secret'), + }); + } + + async validate(payload: any) { + return { userId: payload.sub, username: payload.username }; + } +} diff --git a/src/auth/public.decorator.ts b/src/auth/public.decorator.ts new file mode 100644 index 0000000..b3845e1 --- /dev/null +++ b/src/auth/public.decorator.ts @@ -0,0 +1,4 @@ +import { SetMetadata } from '@nestjs/common'; + +export const IS_PUBLIC_KEY = 'isPublic'; +export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 06e5902..558b8fd 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -13,6 +13,7 @@ import { import { UsersService } from './users.service'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; +import {Public} from "../auth/public.decorator"; @Controller({ path: 'users', @@ -30,6 +31,7 @@ export class UsersController { }; } + @Public() @Get() async findAll(@Query('page') page: number) { const [data, count] = await this.usersService.findAll(page);