이전 파트에서 구현하였던 auth 인증 절차에서 Token 값을 쿠키에 저장하는 부분을 추가하려고 합니다.
$ npm i --save cookie-parser
$ npm i --save-dev @types/cookie-parser
이전 로직에서는 Access Token을 그대로 반환했지만 토큰만을 반환하여 cookie에 저장해야합니다.
/src/auth/auth.service.ts
...생략
@Injectable()
export class AuthService {
...생략
async login(user: User) {
const payload = { username: user.username, sub: user.id };
const token = this.jwtService.sign(payload);
return token;
}
}
/src/app.controller.ts
import { Controller, Get, Post, Req, Res, UseGuards } from '@nestjs/common';
import { Response } from 'express';
import { AuthService } from './auth/auth.service';
import { LocalAuthGuard } from './auth/guards/local-auth.guard';
import { Public } from './skip-auth.decorator';
@Controller()
export class AppController {
constructor(private authService: AuthService) {}
@Public()
@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Req() req, @Res({ passthrough: true }) res: Response) {
const token = await this.authService.login(req.user);
res.cookie('Authentication', token, {
domain: 'localhost',
path: '/',
httpOnly: true,
});
}
@Get('profile')
getProfile(@Req() req) {
return req.user;
}
}
쿠키에 값을 저장합니다. 저장하기 위하여 res을 만들어줘야합니다.
반환된 Token 값을 쿠키에 저장합니다.
/src/main.ts
import { NestFactory } from '@nestjs/core';
import * as cookieParser from 'cookie-parser';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(cookieParser());
await app.listen(3000);
}
bootstrap();
저장된 쿠키값의 토큰 값이 올바른지 JWT를 사용했던 모든 곳에서 확인해야 함으로 JwtStrategy에서 확인하는 코드를 작성합니다.
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { jwtConstants } from '../constants';
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromExtractors([
(request) => {
return request?.cookies?.Authentication;
},
]),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
다음 포스트에서 수정될 사항