Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge: 리프레시 토큰 적용 및 API 문서 포맷 변경 #25

Merged
merged 7 commits into from
Jan 28, 2024

Conversation

Zamoca42
Copy link
Member

PR 체크리스트

아래 항목을 확인해 주세요:

  • 커밋 메시지가 우리의 가이드라인을 따르고 있는지 확인하세요
  • 변경 사항에 대한 테스트가 추가되었는지 확인하세요 (버그 수정 / 기능 추가)
  • 문서가 추가되거나 업데이트되었는지 확인하세요 (버그 수정 / 기능 추가)

PR 유형

이 PR은 어떤 종류의 변경을 가져오나요?

  • 버그 수정
  • 새로운 기능 추가
  • 코드 스타일 업데이트 (서식, 로컬 변수)
  • 리팩터링 (기능 변경 없음, API 변경 없음)
  • 빌드 관련 변경
  • CI 관련 변경
  • 문서 내용 변경
  • 애플리케이션 / 인프라 변경
  • 기타... 설명:

관련 이슈

이슈 번호: #20 #21

현재 동작은 무엇인가요?

  • 액세스 토큰만을 사용한 로그인 인증 및 인가
  • API 문서로 Swagger 문서 사용

새로운 동작은 무엇인가요?

  • 리프레시 토큰 적용
  • 리프레시 토큰을 쿠키에 적용
  • 만료된 액세스토큰과 리프레시 토큰으로 새로운 토큰 발급
  • API 문서 형식을 Scalar 문서로 변경

이 PR은 호환성 변경을 도입하나요?

  • 아니요

기타 정보

API 문서 스크린샷

스크린샷 2024-01-28 오전 2 05 27

인증 관련 참고링크들

- req-credential-body.dto.ts -> req-auth-body.dto.ts
- res-credential.dto.ts -> res-auth.dto.ts
- req-auth-token.dto.ts 추가

Related to #21
- 컨트롤러에서 리프레시 토큰, 엑세스 토큰을 가져오는 로직을 데코레이터로 분리
- AllowAny를 데코레이터로 이동

Related to #21
- 리프레시 토큰을 쿠키에 저장하도록 설정
- 쿠키 설정을 위한 모듈 설치
- 쿠키 설정을 위한 모듈 설정
- 쿠키 설정을 위한 모듈을 main.ts에 적용
- 리프레시 토큰을 가지고 액세스 토큰을 재발급하는 로직 추가

Related to #21
- 패키지 설치
- Swagger 문서를 Scalar 문서로 변경
- main.ts에 Scalar 설정 추가
- /api prefix 제거
- setGlobalPrefix 제외
- 문서 url path를 api/swagger -> /reference로 변경

Related to #20
- 리프레시 토큰 쿠키의 만료시간을 2주로 설정
Related to #21
- 기본 다크모드 적용
- default -> moon 테마로 변경

Related to #20
- supabase 서비스에서 anon 변수 제외

Related to #21
Copy link
Contributor

@sheepdog13 sheepdog13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다
refreshToken의 필요성이랑 JWT 방식의 인증의 flow를 배울 수 있어서 좋았습니다

Comment on lines +20 to +29
@SwaggerAPI({ name: '로그인', allowAny: true, model: AuthResponse })
async signIn(
@Body() request: UserCredential,
@Res({ passthrough: true }) response: Response,
) {
const result = await this.authService.signInWith(request.toCredentials());
response.cookie('refreshToken', result.refreshToken, cookieOptions);
return ResponseEntity.OK_WITH(
`Successfully login ${request.email}`,
new CredentialResponse(response),
result,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refreshToken은 보이는데 accessToken은 같이 발급이 안되나요?
accessToken은 유효기간이 어느정도 되나요?

Copy link
Member Author

@Zamoca42 Zamoca42 Jan 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인을 하면 리프레시 토큰과 액세스 토큰이 한번에 발급됩니다.
리프레시 토큰은 쿠키에 저장하고 액세스 토큰은 AuthResponse 클래스로 직렬화해서 Response Body로 보내집니다.

accessToken은 유효기간이 1시간으로 설정했고 리프레시 토큰의경우 쿠키 만료시간인 14일로 지정했습니다.

AuthResponse

backend/src/auth/res-auth.dto.ts

import { ApiProperty } from '@nestjs/swagger';
import { Session } from '@supabase/supabase-js';
import { Exclude, Expose } from 'class-transformer';

export class AuthResponse {
  @Exclude() private readonly _accessToken: string;
  @Exclude() private readonly _refreshToken: string;
  @Exclude() private readonly _expiresIn: number;
  @Exclude() private readonly _tokenType: string;

  constructor(data: Session) {
    this._accessToken = data.access_token;
    this._refreshToken = data.refresh_token;
    this._expiresIn = data.expires_in;
    this._tokenType = data.token_type;
  }

  @Expose()
  @ApiProperty({
    description: '로그인이 성공한 후 반환된 Access Token 입니다.',
  })
  get accessToken(): string {
    return this._accessToken;
  }

  @Exclude()
  @ApiProperty({
    description: '로그인이 성공한 후 반환된 Refresh Token 입니다.',
  })
  get refreshToken(): string {
    return this._refreshToken;
  }

  @Expose()
  @ApiProperty({
    description: 'Access Token의 만료 시간입니다.',
  })
  get expiresIn(): number {
    return this._expiresIn;
  }

  @Expose()
  @ApiProperty({
    description: 'Access Token의 타입입니다.',
  })
  get tokenType(): string {
    return this._tokenType;
  }
}

로그인 결과 Json

response 에서 accessToken이 보여집니다.

스크린샷 2024-01-28 오후 2 42 58

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 확인했습니다
유효기간은 1시간이군요 감사합니다

@Zamoca42 Zamoca42 merged commit fe7ef93 into main Jan 28, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants