방명록
- [etc] access token & refresh token & JWT2024년 09월 22일 21시 52분 42초에 업로드 된 글입니다.작성자: @kimyu0218
access token과 refresh token
access token과 refresh token은 인증/인가 시스템에서 사용자의 신원을 확인하고 자원 접근을 제어하는 중요한 역할을 수행한다.
access token
인증/인가에 사용되는 토큰이다.
- 짧은 유효기간을 가지기 때문에 탈취되더라도 보안 위험이 적다. (하지만 자주 갱신해야 한다)
- 각 요청마다 토큰을 확인하여 인증하기 때문에 세션 관리의 부담을 줄일 수 있다.
🤔 access token이 세션에 비해 갖는 장점
- 비상태 : 사용자 요청이 올 때마다 세션 스토리지에서 사용자의 세션 정보를 조회할 필요가 없다. (= 단순 토큰 검증 만으로 상태 정보를 확인할 수 있다! 데이터베이스 조회 부담 X)
- 확장성 : 서버 간에 세션 정보를 동기화할 필요가 없으므로 동기화 문제가 발생하지 않고, 로드 밸런싱과 수평 확장에 유리하다.
refresh token
access token이 만료되었을 때 새로운 access token을 발급받기 위해 사용하는 토큰이다.
- 긴 유효기간을 가지기 때문에 탈취되면 보안 위험이 발생할 수 있다.
- 사용자는 다시 로그인할 필요없이 새로운 access token을 받을 수 있기 때문에 사용자 경험이 향상된다.
access token과 refresh token 시나리오
- 사용자가 어플리케이션에 로그인하면 서버는 access token과 refresh token을 발급한다.
- access token과 refresh token은 사용자의 정보를 담고 있으며, 서명하여 변조를 방지한다.
- 웹 어플리케이션의 refresh token의 경우, HTTP Only 쿠키에 저장하여 스크립트로 접근할 수 없도록 한다.
- 모바일 어플리케이션의 refresh token의 경우, refresh token을 body에 포함하여 보낸다.
- 서버는 Redis에 refresh token을 TTL을 걸어 저장한다.
- 사용자가 요청을 보내면 access token을 사용하여 인증한다.
- access token이 만료되면, refresh token을 사용하여 새로운 access token을 요청한다.
- 서버는 refresh token을 확인하고, 유효한 경우 새로운 access token을 발급한다. 유효하지 않는 경우, 사용자는 다시 로그인한다.
- 이때, 서버는 Redis를 통해 refresh token의 유효성을 빠르게 검증할 수 있다.
JWT; JSON Web Token
JWT는 두 개체 간에 정보를 안전하게 전송하기 위해 사용하는 방법이다. 주로 인증에서 많이 사용된다.
JWT는 세 가지 부분으로 구성된다. 각 부분은 `[HEADER].[PAYLOAD].[SIGNATURE]`과 같이 `.`으로 구분되며 Base64URL로 인코딩되어 있다.- header : 토큰의 유형`typ`과 서명 알고리즘`alg`을 지정한다.
- payload (= claims) : 전송할 정보를 포함하는 부분으로 JSON 형식으로 구성된다. (인코딩 O 암호화 X)
- registered claims : 미리 정의된 claim
- `iss` 토큰 발급자, `sub` 토큰의 주체, `aud` 토큰의 대상 (= 수신자)
- `exp` 만료 시간, `nbf` 이 시간 이전에는 토큰이 유효하지 않음, `iat` 토큰 발급 시간
- public claims : 사용자 정의 claim (ex. 이메일, 이름 등)
- private claims : 다른 어플리케이션과 공유하지 않는 claim (ex. 사용자 권한/역할)
- registered claims : 미리 정의된 claim
- signature : header와 payload를 비밀키로 서명한 부분으로 무결성을 보장한다.
// io.jsonwebtoken return Jwts.builder() .setSubject(subject) .setIssuedAt(iat) .setExpiration(exp) .signWith(SignatureAlgorithm.HS256, secret) .compact();
'backend' 카테고리의 다른 글
[etc] Spring REST Docs와 Swagger UI를 사용한 API 문서화 (0) 2025.01.17 [etc] CORS 이해하기 (Feat. *에서 탈출하기) (1) 2024.01.21 [etc] passport를 이용하여 인증/인가 구현하기 (with nest) (0) 2024.01.18 [etc] graceful shutdown으로 사용자 경험 저하 방지하기 (with docker & nest) (0) 2024.01.15 [etc] winston과 sentry로 서버가 터지는 이유 분석하기 (1) 2024.01.13 다음글이 없습니다.이전글이 없습니다.댓글