diff --git a/apps/backend/package.json b/apps/backend/package.json index c53ae47..8ae0d85 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -55,6 +55,7 @@ "socket.io": "^4.8.1", "sqlite3": "^5.1.7", "typeorm": "^0.3.20", + "uuid": "^11.0.3", "ws": "^8.14.2", "y-prosemirror": "^1.2.12", "y-protocols": "^1.0.6", diff --git a/apps/backend/src/auth/auth.controller.ts b/apps/backend/src/auth/auth.controller.ts index ff4e1c3..d575c17 100644 --- a/apps/backend/src/auth/auth.controller.ts +++ b/apps/backend/src/auth/auth.controller.ts @@ -41,11 +41,13 @@ export class AuthController { // 네이버 인증 후 사용자 정보 반환 const user = req.user; - // primary Key인 id 포함 payload 생성함 - // TODO: 여기서 권한 추가해야함 + // primary Key인 id 포함 payload 생성, access token 만들기 const payload = { sub: user.id }; const accessToken = this.tokenService.generateAccessToken(payload); - const refreshToken = this.tokenService.generateRefreshToken(payload); + + // access token 만들어서 db에도 저장 + const refreshToken = this.tokenService.generateRefreshToken(); + this.authService.updateRefreshToken(user.id, refreshToken); // 토큰을 쿠키에 담아서 메인 페이지로 리디렉션 this.tokenService.setAccessTokenCookie(res, accessToken); @@ -67,11 +69,13 @@ export class AuthController { /// 카카오 인증 후 사용자 정보 반환 const user = req.user; - // primary Key인 id 포함 payload 생성함 - // TODO: 여기서 권한 추가해야함 + // primary Key인 id 포함 payload 생성, access token 만들기 const payload = { sub: user.id }; const accessToken = this.tokenService.generateAccessToken(payload); - const refreshToken = this.tokenService.generateRefreshToken(payload); + + // access token 만들어서 db에도 저장 + const refreshToken = this.tokenService.generateRefreshToken(); + this.authService.updateRefreshToken(user.id, refreshToken); // 토큰을 쿠키에 담아서 메인 페이지로 리디렉션 this.tokenService.setAccessTokenCookie(res, accessToken); @@ -94,7 +98,6 @@ export class AuthController { // 클라이언트가 사용자의 외부 id(snowflakeId) + 이름을 알 수 있는 엔드포인트 // auth/profile - // TODO: 사용자 지정 닉네임 + 프로필 이미지도 return하게 확장 @Get('profile') @UseGuards(JwtAuthGuard) // JWT 인증 검사 async getProfile(@Req() req) { diff --git a/apps/backend/src/auth/auth.service.ts b/apps/backend/src/auth/auth.service.ts index 90c47ca..4d9b1ff 100644 --- a/apps/backend/src/auth/auth.service.ts +++ b/apps/backend/src/auth/auth.service.ts @@ -31,6 +31,7 @@ export class AuthService { async findUserById(id: number): Promise { return await this.userRepository.findOneBy({ id }); } + async updateUser(id: number, dto: UpdateUserDto) { // 유저를 찾는다. const findUser = await this.userRepository.findOneBy({ id }); @@ -44,4 +45,34 @@ export class AuthService { const newPage = Object.assign({}, findUser, dto); await this.userRepository.save(newPage); } + + async compareStoredRefreshToken( + id: number, + refreshToken: string, + ): Promise { + // 유저를 찾는다. + const user = await this.userRepository.findOneBy({ id }); + + // 유저가 없으면 오류 + if (!user) { + throw new UserNotFoundException(); + } + + // DB에 있는 값과 일치하는지 비교한다 + return user.refreshToken === refreshToken; + } + + async updateRefreshToken(id: number, refreshToken: string) { + // 유저를 찾는다. + const user = await this.userRepository.findOneBy({ id }); + + // 유저가 없으면 오류 + if (!user) { + throw new UserNotFoundException(); + } + + // 유저의 현재 REFRESH TOKEN 갱신 + user.refreshToken = refreshToken; + await this.userRepository.save(user); + } } diff --git a/apps/backend/src/auth/token/token.service.ts b/apps/backend/src/auth/token/token.service.ts index 3d1c499..802968c 100644 --- a/apps/backend/src/auth/token/token.service.ts +++ b/apps/backend/src/auth/token/token.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { Response } from 'express'; +import { v4 as uuidv4 } from 'uuid'; const HOUR = 60 * 60; const DAY = 24 * 60 * 60; @@ -17,7 +18,10 @@ export class TokenService { }); } - generateRefreshToken(payload: any): string { + generateRefreshToken(): string { + const payload = { + jti: uuidv4(), + }; return this.jwtService.sign(payload, { expiresIn: FIVE_MONTHS, }); diff --git a/apps/backend/src/user/user.entity.ts b/apps/backend/src/user/user.entity.ts index d4ecdd8..179aee2 100644 --- a/apps/backend/src/user/user.entity.ts +++ b/apps/backend/src/user/user.entity.ts @@ -36,6 +36,9 @@ export class User { @Column({ nullable: true }) profileImage: string; + @Column({ nullable: true }) + refreshToken: string; + @CreateDateColumn() createdAt: Date; } diff --git a/yarn.lock b/yarn.lock index fa74113..ecc38d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10798,6 +10798,11 @@ uuid@9.0.1, uuid@^9.0.0, uuid@^9.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== +uuid@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.0.3.tgz#248451cac9d1a4a4128033e765d137e2b2c49a3d" + integrity sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg== + uvu@^0.5.0: version "0.5.6" resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"