-
Notifications
You must be signed in to change notification settings - Fork 1
[준섭] 1121(화) 개발기록 ‐ SignIn시 RefreshToken 발급 및 Redis에 저장
송준섭 edited this page Nov 21, 2023
·
1 revision
// signin-user.dto.ts
import ...
export class SignInUserDto {
@ApiProperty({
description: '로그인용 아이디',
example: 'test user',
required: true,
})
@IsNotEmpty({ message: UserEnum.USERNAME_NOTEMPTY_MESSAGE as string })
@IsString({ message: UserEnum.USERNAME_ISSTRING_MESSAGE as string })
@IsUsername()
username: string;
@ApiProperty({
description: '비밀번호',
example: 'test password',
required: true,
})
@IsNotEmpty({ message: UserEnum.PASSWORD_NOTEMPTY_MESSAGE as string })
@IsString({ message: UserEnum.PASSWORD_ISSTRING_MESSAGE as string })
@IsPassword()
password: string;
}
[준섭] 1121(화) 개발기록 ‐ SignUpDto에 ClassValidator 적용에서 만들었던 데코레이터 @IsUsername()
과 @IsPassword()
를 재사용하였습니다.
// auth.service.ts
async signIn(signInUserDto: SignInUserDto) {
const { username, password } = signInUserDto;
const user = await this.authRepository.findOneBy({ username });
if (user && (await bcrypt.compare(password, user.password))) {
const accessTokenPayload = { username, id: user.id, type: 'access' };
const refreshTokenPayload = { username, id: user.id, type: 'refresh' };
const [accessToken, refreshToken] = await Promise.all([
this.jwtService.sign(accessTokenPayload), // accessToken은 expiresIn이 60 * 60(1시간)
this.jwtService.sign(refreshTokenPayload, { expiresIn: 60 * 60 * 24 }), // refreshToken은 하루
]);
return { accessToken, refreshToken };
} else {
throw new UnauthorizedException('login failed');
}
}
현재 우리 프로젝트의 jwtConfig
에는 원래 expiresIn
옵션이 60 * 60으로 1시간으로 되어있다.
그러나 refreshToken
은 accessToken
보다 더 길게 유효 기간을 잡아야 하므로 하루로 늘렸다.
이 유효 기간에 관해서는 얼마가 좋을 지 생각이 필요할 듯 하다.
그렇게 토큰을 발급하면 AuthController
에서 이 토큰을 받아 사용한다.
async signIn(
@Body() signInUserDto: SignInUserDto,
@Res({ passthrough: true }) res: Response,
) {
const tokens = await this.authService.signIn(signInUserDto);
res.cookie('accessToken', tokens.accessToken, {
path: '/',
httpOnly: true,
});
res.cookie('refreshToken', tokens.refreshToken, {
path: '/',
httpOnly: true,
});
return tokens;
}
이렇게 쿠키에 담아서 보내면 다음과 같이 쿠키가 설정된다.
이 두 토큰의 값을 디코딩 해보았다.
- accessToken
- refreshToken
정보가 잘 담겨있는 모습을 확인했다.
유효 기간도 accessToken은 1시간, refreshToken은 하루가 잘 적용되어 있었다.
// auth.service.ts
async signIn(signInUserDto: SignInUserDto) {
const { username, password } = signInUserDto;
const user = await this.authRepository.findOneBy({ username });
if (!(user && (await bcrypt.compare(password, user.password)))) {
throw new UnauthorizedException('login failed');
}
const accessTokenPayload = { username, id: user.id, type: 'access' };
const refreshTokenPayload = { username, id: user.id, type: 'refresh' };
const [accessToken, refreshToken] = await Promise.all([
this.jwtService.sign(accessTokenPayload),
this.jwtService.sign(refreshTokenPayload, { expiresIn: 60 * 60 * 24 }),
]);
// redis에 저장 (키로 username, 값으로 refreshToken)
this.redisRepository.set(username, refreshToken);
return { accessToken, refreshToken };
}
처음 명령어는 SignIn 전, 다음 명령어는 SignIn 후.
username이 키로 추가된 모습.
값에는 refreshToken이 그대로 담겨있다.
© 2023 debussysanjang
- 🐙 [가은] Three.js와의 설레는 첫만남
- 🐙 [가은] JS로 자전과 공전을 구현할 수 있다고?
- ⚽️ [준섭] NestJS 강의 정리본
- 🐧 [동민] R3F Material 간단 정리
- 👾 [재하] 만들면서 배우는 NestJS 기초
- 👾 [재하] GitHub Actions을 이용한 자동 배포
- ⚽️ [준섭] 테스트 코드 작성 이유
- ⚽️ [준섭] TypeScript의 type? interface?
- 🐙 [가은] 우리 팀이 Zustand를 쓰는 이유
- 👾 [재하] NestJS, TDD로 개발하기
- 👾 [재하] AWS와 NCP의 주요 서비스
- 🐰 [백범] Emotion 선택시 고려사항
- 🐧 [동민] Yarn berry로 모노레포 구성하기
- 🐧 [동민] Vite, 왜 쓰는거지?
- ⚽️ [준섭] 동시성 제어
- 👾 [재하] NestJS에 Swagger 적용하기
- 🐙 [가은] 너와의 추억을 우주의 별로 띄울게
- 🐧 [동민] React로 멋진 3D 은하 만들기(feat. R3F)
- ⚽️ [준섭] NGINX 설정
- 👾 [재하] Transaction (트랜잭션)
- 👾 [재하] SSH 보안: Key Forwarding, Tunneling, 포트 변경
- ⚽️ [준섭] MySQL의 검색 - LIKE, FULLTEXT SEARCH(전문검색)
- 👾 [재하] Kubernetes 기초(minikube), docker image 최적화(멀티스테이징)
- 👾 [재하] NestJS, 유닛 테스트 각종 mocking, e2e 테스트 폼데이터 및 파일첨부
- 2주차(화) - git, monorepo, yarn berry, TDD
- 2주차(수) - TDD, e2e 테스트
- 2주차(목) - git merge, TDD
- 2주차(일) - NCP 배포환경 구성, MySQL, nginx, docker, docker-compose
- 3주차(화) - Redis, Multer 파일 업로드, Validation
- 3주차(수) - AES 암복호화, TypeORM Entity Relation
- 3주차(목) - NCP Object Storage, HTTPS, GitHub Actions
- 3주차(토) - Sharp(이미지 최적화)
- 3주차(일) - MongoDB
- 4주차(화) - 플랫폼 종속성 문제 해결(Sharp), 쿼리 최적화
- 4주차(수) - 코드 개선, 트랜잭션 제어
- 4주차(목) - 트랜잭션 제어
- 4주차(일) - docker 이미지 최적화
- 5주차(화) - 어드민 페이지(전체 글, 시스템 정보)
- 5주차(목) - 감정분석 API, e2e 테스트
- 5주차(토) - 유닛 테스트(+ mocking), e2e 테스트(+ 파일 첨부)
- 6주차(화) - ERD
- 2주차(화) - auth, board 모듈 생성 및 테스트 코드 환경 설정
- 2주차(목) - Board, Auth 테스트 코드 작성 및 API 완성
- 3주차(월) - Redis 연결 후 RedisRepository 작성
- 3주차(화) - SignUpUserDto에 ClassValidator 적용
- 3주차(화) - SignIn시 RefreshToken 발급 및 Redis에 저장
- 3주차(화) - 커스텀 AuthGuard 작성
- 3주차(수) - SignOut시 토큰 제거
- 3주차(수) - 깃헙 로그인 구현
- 3주차(토) - OAuth 코드 통합 및 재사용
- 4주차(수) - NestJS + TypeORM으로 MySQL 전문검색 구현
- 4주차(목) - NestJS Interceptor와 로거
- [전체] 10/12(목)
- [전체] 10/15(일)
- [전체] 10/30(월)
- [FE] 11/01(수)~11/03(금)
- [전체] 11/06(월)
- [전체] 11/07(화)
- [전체] 11/09(목)
- [전체] 11/11(토)
- [전체] 11/13(월)
- [BE] 11/14(화)
- [BE] 11/15(수)
- [FE] 11/16(목)
- [FE] 11/19(일)
- [BE] 11/19(일)
- [FE] 11/20(월)
- [BE] 11/20(월)
- [BE] 11/27(월)
- [FE] 12/04(월)
- [BE] 12/04(월)
- [FE] 12/09(금)
- [전체] 12/10(일)
- [FE] 12/11(월)
- [전체] 12/11(월)
- [전체] 12/12(화)