* 로그인 과정 복습 (Basic token 이용)
- 이메일 : 비밀번호를 encoding
- Basic Ymfldgkmdfkgdbdfbdf를 요청
- 뒷부분만 파싱
- 다시 디코딩
- email, pw 나옴
- db에서 조회
- user 객체 리턴
* req에 user 넣기
/**
* req.header.authorization 의 토큰으로
* user를 가와서
* req.user에 넣는 가드
*/
@Injectable()
export class BasicTokenGuard implements CanActivate {
constructor(private readonly authService: AuthService) {} //런타임에서 DI에서 주입해줌
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
// {authorization : Basic fibntbdffg}
// fibntbdffg
const rawToken = req.headers.authorization;
if(!rawToken){
throw new UnauthorizedException('토큰이 없습니다!');
}
const token = this.authService.extractTokenFromHeader(rawToken,false);
const {email, password} = this.authService.decodeBasicToken(rawToken);
const user = await this.authService.authenticationWithEmailAndPassword({
email,
password,
});
req.user = user;
return true; //가드 통과
}
}
/**
* Header중 authorization 필드만 가져옴
*/
@Post('/login/email')
@UseGuards(BasicTokenGuard)
postLoginEmail(
@Headers('authorization') rawToken: string,){
const token = this.authService.extractTokenFromHeader(rawToken, false);
const credentials = this.authService.decodeBasicToken(token); // {email, password} 객체
return this.authService.loginWithEmail(credentials);
}
* bearer 토큰 가드
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from "@nestjs/common";
import { AuthService } from "../auth.service";
import { UsersService } from "../../users/users.service";
/**
* Bearer sdfjdsivjlivjdlfiv 토큰을 받아서
* 파싱후
* req에 user, token, tokenType 넣기
*/
@Injectable()
export class BearerTokenGuard implements CanActivate {
constructor(private readonly authService: AuthService,
private readonly usersService : UsersService) {} //런타임에서 DI에서 주입해줌
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
// {authorization : Basic fibntbdffg}
// fibntbdffg
const rawToken = req.headers.authorization;
if(!rawToken){
throw new UnauthorizedException('토큰이 없습니다!');
}
const token = this.authService.extractTokenFromHeader(rawToken,true);
const result = await this.authService.verifyToken(token);
/**
* req에 넣을정보
* 1) 서용자 정보
* 2) token
* 3) token type - access | refresh
*/
const user = await this.usersService.getUserByEmail(result.email);
req.user = user;
req.token = token;
req.tokenType = result.type;
return true; //가드 통과
}
}
/**
* 토큰이 엑세스 토큰인지 확인
*/
@Injectable()
export class AccessTokenGuard extends BearerTokenGuard {
async canActivate(context: ExecutionContext): Promise<boolean> {
await super.canActivate(context);
const req = context.switchToHttp().getRequest();
if(req.tokenType !== 'access'){
throw new UnauthorizedException('Access Token이 아닙니다.');
}
return true; //다음 미들웨어로
}
}
/**
* 토큰이 refresh 토큰인지 확인
*/
@Injectable()
export class RefreshTokenGuard extends BearerTokenGuard {
async canActivate(context: ExecutionContext): Promise<boolean> {
await super.canActivate(context);
const req = context.switchToHttp().getRequest();
if(req.tokenType !== 'refresh'){
throw new UnauthorizedException('Refresh Token이 아닙니다.');
}
return true; //다음 미들웨어로
}
}
@Post('token/access')
@UseGuards(RefreshTokenGuard) //리프레시 토큰으로만 엑세스토큰 발급가능
postTokenAccess(
@Headers('authorization') rawToken: string,){
const token = this.authService.extractTokenFromHeader(rawToken, true);
const newToken = this.authService.rotateToken(token,false);
/**
* {accessToken : {token}}
*/
return {
accessToken: newToken,
}
}
@Post('token/refresh')
@UseGuards(RefreshTokenGuard)
postTokenRefresh(
@Headers('authorization') rawToken: string,){
const token = this.authService.extractTokenFromHeader(rawToken, true);
const newToken = this.authService.rotateToken(token,true);
/**
* {refreshToken : {token}}
*/
return {
refreshToken: newToken,
}
}
'JS > Nest.js' 카테고리의 다른 글
[Nest] 커스텀 데코리이터 => controller 코드 간소화 (0) | 2024.09.20 |
---|---|
[Nest] DI 실습 export service, import module, Nest can't resolve dependencies of the 해결, 게시글 생성제한 구현 (0) | 2024.09.20 |
[Nest] 커스텀 파이프 => 비밀번호 길이 제한 구현 (0) | 2024.09.20 |
[Nest] Jwt 토큰 재발급 구현 (0) | 2024.09.18 |
[Nest] base64 토큰 인증 구현 (0) | 2024.09.18 |