1. Access Token이 무엇인가?
Access Token은 사용자의 인증(ex : 로그인)이 완료된 후 해당 사용자를 인증하는 용도로 발급하는 토큰입니다.
이전에 쿠키(Cookie)에 jwt를 설정하고, 지정된 만료 시간이
지나면 인증이 만료되는 구조 또한 Access Token이라 부른다.
인증 요청시 Access Token을 사용하면,
토큰을 생성할 때 사용한 비밀키(Secret Key)로 인증을 처리하게 됩니다.
이 방식은 복잡한 설계나 여러 분기 처리 없이 코드를 구현할 수 있다는 장점을 가지고 있습니다.
Access Token은 Stateless(무상태) 즉, Node.js 서버가 재시작되더라도 동일하게 작동하게 됩니다.
이는 jwt를 이용해 사용자의 인증 여부는 확인할 수 있지만, 처음 토큰을 발급한 사용자가 정말
그 사용자인지는 확인할 수 없습니다.
Access Token은 그 자체로도 사용자 인증에 필요한 모든 정보를 가지고 있습니다.
그렇기 때문에, 토큰을 가지고 있는 시간이 늘어날 수록, 탈취되었을 때 피해 규모는 더욱 커지게 됩니다.
토큰이 탈취되었다 하더라도, 서버에서는 해당 토큰이 탈취된 토큰인지 알 수 없으며,
강제로 토큰을 만료시킬 수도 없습니다. 따라서 서버는 언제나 토큰이 탈취될 수 있다는 가정 하에,
피해를 최소화할 수 있는 방향으로 개발을 진행해야 합니다.
2. Refresh Token이 무엇인가?
Refresh Token은 사용자의 모든 인증 정보를 담고 있는 Access Token과는 달리,
특정 사용자가 Access Token을 발급받기 위한 목적으로만 사용됩니다.
Refresh Token은 사용자의 인증 정보를 검증하는데 사용되며, 이를 서버에서 관리합니다.
서버는 Refresh Token을 디코딩하여 사용자의 정보를 확인하게 됩니다.
이 방식은 필요한 경우 서버에서 강제로 토큰을 만료시킬 수 있으며,
사용자의 인증 상태를 언제든지 서버에서 제어할 수 있다는 장점을 가지고 있습니다.
Refresh Token을 통해 AccessToken을 발급하면 토큰이 탈취당한 경우에 대비하여
피해를 최소화시킬 수 있습니다.
OTP인증 처럼, 인증 정보는 짧은 시간동안만 사용하고,
주기적으로 토큰을 재발급함으로써, 토큰이 유출되더라도
그 피해가 오랜 시간 동안 지속되는 것이 아니라,
짧은 기간 동안만 사용 가능하도록 제한하여 피해를 최소화할 수 있습니다.
3. Refresh Token 만들기
Refresh Token은 사용자가 서버와 최초 인증시에 발급을 받게 됩니다.
와 같이 만들어 볼 계획입니다.
새로운 디렉토리를 만들고
1) 추가적인 yarn Package 설치하기
yarn init -y
# yarn을 이용해 프로젝트를 초기화 합니다
yarn add express jsonwebtoken cookie-parser
# express, jsonwebtoken, cookie-parser 패키지를 설치합니다.
package.json 파일에 type : "module" 추가하기
2) Refresh Token과 Access Token을 발급하는 API를 만들어봅니다!
app.js 구현하기
그 후,
Insomnia에서 "localhost:3019/tokens" 에 접속하면
Client에게 토큰이 발급 됐다는 문구가 응답으로 오게 됩니다.
그리고,
accessToken과 refreshToken이 정상 발급된걸 확인할 수 있습니다.
(현재 토큰은 Jwt로 암호화하지 않은 상태 입니다.)
그리고
를 확인해보면,
위와 같이,
id는
와 동일하고,
ip는
왼쪽에는 IPv6가 존재하고, 오른쪽은 실제 IPv4 주소가 있는 것을 확인할 수 있습니다.
그리고,
userAgent에는
위와 같이 어떤 방식으로 서버에 요청을 보냈는지 확인할 수 있습니다.
추가 학습 ) Refresh Token의 정보는어디서 관리해야 하나요?
실제 서비스에서는 별도의 DB 테이블에서 Refresh Token을 저장하고 관리해야합니다.
이렇게 할 경우, Refresh Token 검증 작업을 MySQL과 같은 데이터베이스를
조회함과 동시에 함께 처리할 수 있게 됩니다.
ex)
이 외에도 ip 또는 user-Agent와 같은 정보를 추가할 수 있습니다.
사용자가 POST/tokens API를 호출하면, 이 API는 Access Token과 Refresh Token을
각각 하나 씩 발급하도록 구현하였습니다. 이 부분을 로그인 기능으로 생각하면 편하겠죠?
3) Access Token을 검증하는 API를 만들어봅니다!
서버에서 발급받은 Access Token을 검증하는 GET /tokens/validate API를 만들어보겠습니다.
Insomnia에서 localhost:3019/tokens/validate 에 접근해보면,
Client는 유효하지 않은 Access Token이라는 응답을 받을 수 있습니다.
다시 localhost:3019/tokens로
token을 발행하고 localhost:3019/tokens/validate 에 접근해보면,
Client는 PayLoad를 가진 Token이 성공적으로 인증 됐다는
문구를 확인할 수 있습니다.
처음 Access Token이 유효하지 않다는 에러 이유는
완료 기간을 10초로 했기 때문에,
10초가 지나면 Token이 사라지기 때문입니다.
10초가 지난 이후 localhost:3019/tokens/validate 에 접근해보면,
다시 Client는 유효하지 않다는 응답을 받게 되는 것을 확인할 수 있습니다.
4) Refresh Token으로 Access Token 재발급하는 API 만들기
서버에서 발급받은 Access Token을 검증하는 GET/tokens/validate API를 만들어보겠습니다.
Insomnia에서 localhost:3019/tokens/refresh에 접근해보면,
Clinet에게 새롭게 토큰이 발급되는 걸 확인할 수 있습니다.
하지만, 현재
tokenStoreages를 DB의 Table이 아닌
객체로 구현해놨기 때문에 서버를 껐다 키면 토큰 정보가 삭제되는 문제가 있습니다.
tokenStorages를 테이블로 구성해야한다.
5) 그래서 우리는 어떤 인증 방식을 사용해야 하나요?
개발을 진행하다보면, 어떤 기술이든 모든 상황에서 강점을 가지는 기술은 존재하지 않습니다.
이런 이유로 새로운 기술을 도입할 때는 현재 상황에 가장 알맞는 최적의 선택을 하는 것이 중요합니다.
프로젝트를 신속하게 구현해야 하거나 사용자의 요청에 대한 인증을 최소화하려는 목표가 있다면
Access Token만 사용할 것입니다.
반면, 보안성을 중요하게 여기고 서버를 더욱 견고하게 구성해야한다면 Refresh Token의 사용을 고려할 것 입니다.
'Node 강의 > 숙련' 카테고리의 다른 글
2-4 [게시판 프로젝트] 게시글 생성 API (2) | 2024.09.09 |
---|---|
2-3 [게시판 프로젝트] 미들웨어 (0) | 2024.09.09 |
2-1 [게시판 프로젝트] 인증 인가 (로그인, 회원 가입 API) (0) | 2024.09.08 |
1-11 [게시판 프로젝트] 시작하기 (DB 설계 및 Prisma 모델 정의) (0) | 2024.09.08 |
1-10 JWT (0) | 2024.09.07 |