
npm i @nestjs/jwt
User 생성
nest g res user ↵
REST API 선택
Would you like to generate CRUD entry points? (Y/n) N 입력
파일 생성 확인
수정
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
@Module({
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService], +
})
export class UsersModule {}
import { Injectable } from '@nestjs/common';
export type User = any;
@Injectable()
export class UsersService {
private users = [
{
id: 1,
username: 'jjjj',
password: '111111',
},
{
id: 2,
username: 'dddd',
password: '222222',
},
];
async findOne(username: string): Promise<User | undefined> {
return this.users.find((user) => user.username === username);
}
async findAll(): Promise<User[]> {
return this.users;
}
}
Auth 생성
nest g res auth ↵
REST API 선택
Would you like to generate CRUD entry points? (Y/n) N 입력
파일 생성 확인
수정
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from 'src/users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
@Module({
imports: [
UsersModule,
JwtModule.register({
global: true,
secret: jwtConstants.secret,
signOptions: { expiresIn: '1h' },
}),
],
providers: [AuthService],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
import {
Controller,
HttpStatus,
Body,
HttpCode,
Post,
Request,
UseGuards,
Get,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { SignInDto } from './dto/SignInDto';
import { Public } from 'src/util/public.meta';
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@HttpCode(HttpStatus.OK)
@Public()
@Post('login')
async signIn(@Body() signInDto: SignInDto) {
return this.authService.signIn(signInDto.username, signInDto.password);
}
@Get('profile')
getProfile(@Request() req) {
return 'authenticated success';
}
@Public()
@Get('all')
finaAll() {
return 'not authenticated';
}
}
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly usersService: UsersService,
private readonly jwtService: JwtService,
) {}
async signIn(
username: string,
password: string,
): Promise<{ access_token: string }> {
const user = await this.usersService.findOne(username);
if (user?.password !== password) {
throw new UnauthorizedException();
}
const payload = { sub: user.userId, username: user.username };
return { access_token: await this.jwtService.sign(payload) };
}
}
meta파일 생성
import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
guard파일 생성
/src/auth/auth.guard.ts
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Observable } from 'rxjs';
import { jwtConstants } from './constants';
import { Request } from 'express';
import { Reflector } from '@nestjs/core';
import { IS_PUBLIC_KEY } from 'src/util/public.meta';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private readonly jwtService: JwtService,
private readonly reflector: Reflector,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
return true;
}
const request = context.switchToHttp().getRequest<Request>();
const token = this.extractTokenFromHeader(request);
if (!token) {
throw new UnauthorizedException();
}
try {
const payload = await this.jwtService.verifyAsync(token, {
// secret: process.env.JWT_SECRET,
secret: jwtConstants.secret,
});
} catch (e) {
throw new UnauthorizedException();
}
return true;
}
private extractTokenFromHeader(request: Request): string | undefined {
const [type, token] = request.headers.authorization?.split(' ') ?? [];
return type === 'Bearer' ? token : undefined;
}
}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { AuthGuard } from './auth/auth.guard';
@Module({
imports: [AuthModule, UsersModule],
controllers: [AppController],
providers: [
AppService,
{
provide: 'APP_GUARD',
useClass: AuthGuard,
},
],
})
export class AppModule {}