2023. 3. 20. 17:36ㆍSpring
◎ JWT(JSON Web Token)
-> 데이터를 안전하고 간결하게 전송하기 위해 나온 인터넷 표준 인증 방식으로 토큰 인증 방식에서 가장 범용적으로 사용된다.
-> Json 포맷의 토큰 정보를 인코딩하여 인코딩된 토큰 정보를 Secret Key로 서명한 메시지를 Web Token으로 인증 과정에서 사용한다.
◎ JWT 종류
-> 액세스 토큰(Access Token) : 보호된 정보(사용자 이메일, 연락처 등)에 접근할 수 있는 권한 부여에 사용되는 토큰
-> 리프레시 토큰(Refresh Token) : Access Token의 유효기간이 만료되면 Access Token을 발급해주는 토큰. 사용자는 다시 로그인 인증을 할 필요가 없다.
-> 권한을 부여받을 때는 액세스 토큰만 있으면 된다.
-> 만약 액세스 토큰을 공격자가 탈취를 한다면 공격자가 기존 사용자인 것처럼 서버에 여러 요청을 보낼 수 있다. 따라서 액세스 토큰은 비교적 짧은 유효 기간을 부여하여 토큰이 탈취되어도 오랜기간 사용하지 못하도록 막아야 한다.
-> 리프레시 토큰을 탈취당한다면 공격자는 리프레시 토큰으로 액세스 토큰을 발급하여 사용자에게 피해를 입힌다.
◎ JWT 구조
-> JWT는 헤더, 페이로드, 시그니처로 구성되어 있다.
-> Header : 토큰이 어떤 종류인지(JWT 등) 어떤 알고리즘으로 sign(서명)할지 정의한다.
{
"alg": "HS256"
"typ": "JWT"
}
- 위 Json 객체를 base64 방식으로 인코딩하면 JWT의 첫 번째 부분이 완성된다.
-> Payload : 서버에서 활용할 수 있는 사용자의 정보가 담겨있다. 어떤 정보에 접근 가능한지에 대한 권한이 있을 수 있고, 사용자의 이름과 같은 필요한 내용을 담을 수 있다. 민감한 정보는 담지 않는 것이 좋다.
{
"sub": "someInformation",
"name": "hong",
"iat": 192931922
}
- 위 Json 객체를 base64로 인코딩하면 JWT의 두 번째 블록이 완성된다.
-> Signature : 원하는 Secret Key와 헤더에서 지정한 알고리즘을 사용해 헤더와 페이로드에 대해 단방향 암호화를 수행한다. 암호화된 메시지는 토큰의 위변조 유무를 검증하는데 사용된다. 만약 암호화 방법인 HMAC SHA256 알고리즘을 사용하면 Signature는 아래와 같은 형태로 생성된다.
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
※ JWT 사용 예시
- 애플리케이션 A가 gmail과 연동되어 이메일을 읽어와야하는 상황이라고 가정한다.
- 사용자는 gmail 인증서버에 로그인 정보(아이디/패스워드)를 제공한다.
- 인증이 성공하면 JWT를 발급받는다.
- 애플리케이션 A는 JWT를 사용하여 해당 사용자의 이메일을 읽고 사용할 수 있다.
◎ 토큰 기반 인증 절차
1. 클라이언트가 서버에 아이디와 비밀번호를 담아 서버에 로그인 요청을 보낸다.
2. 아이디/비밀번호가 일치하는지 확인하고, 일치하면 클라이언트에게 보낼 암호화된 토큰을 생성한다.
- Access Token 과 Refresh Token을 모두 생성한다. 토큰에 담길 정보(payload)는 사용자를 식별할 정보, 사용자의 권한 정보 등이 된다. Refresh Token으로 새로운 AccessToken을 생성할 것이기 때문에 두 종류의 토큰이 같은 정보를 담을 필요는 없다.
3. 토큰을 클라이언트에게 전송하면, 클라이언트는 토큰을 저장한다.
- 저장하는 위치는 Local Storage나 cookie, Session Storage가 될 수 있다.
4. 클라이언트가 HTTP Header나 쿠키에 토큰을 담아 Request를 전송한다.
- *Bearer authentication을 이용한다.
* Bearer authentication : access Token을 API 서버에 보내서 인증하는 방식
https://learning.postman.com/docs/sending-requests/authorization/#bearer-token
5. 서버는 전송 받은 토큰을 검증하고 서버에서 발급해준 토큰과 일치하는 경우 클라이언트의 요청을 처리하여 응답을 해준다.
◎ JWT의 장점 & 단점
<장점>
1. 상태를 유지하지 않고,(stateless) 확장에 용이한 애플리케이션을 구현하기 좋다.
- 서버에서는 클라이언트에 대한 정보를 저장할 필요 없이 클라이언트가 요청을 보낼때 같이 전달하는 토큰이 정상적인 것인지 검증만 하면 된다.
- 여러 대 서버를 이용한 서비스의 경우 하나의 토큰으로 여러 서버에서 인증이 가능하기 떄문에 JWT사용하는 것이 효율적이다. -> 만약 세션 방식이었다면 모든 서버가 해당 사용자의 세션 정보를 공유하고 있어야 한다.
2. 클라이언트가 request를 전송할 때마다 자격 증명 정보를 전송할 필요가 없다.
- HTTP Basic 같은 인증 방식은 request를 전송할 때마다 자격 증명 정보를 포함해야 하지만 JWT는 토큰이 만료되기 전까지는 한 번만 인증을 수행하면 이후에 request를 전송할 떄는 자격 증명 정보를 전송할 필요가 없다.
3. 인증을 담당하는 시스템을 다른 플랫폼으로 분리하는 것이 용이하다.
- 사용자의 자격 증명 정보를 직접 관리하지 않고, 깃허브, 구글 등의 다른 플랫폼의 자격 증명 정보로 인증하는 것이 가능하다.
- 토큰 생성용 서버를 만들거나 다른 회사에서 토큰 관련 작업을 작업을 맡기는 등 다양한 활용이 가능하다.
4. 권한 부여에 용이하다.
- 토큰의 payload안에 해당 사용자의 권한 정보를 포함하는 것이 용이하다.
<단점>
1. payload는 디코딩이 용이하다.
- payload는 Base64로 인코딩 되기 때문에 토큰을 탈취하여 payload를 디코딩하면 토큰 생성 시 저장한 데이터를 확인할 수 있다. 따라서 payload에는 민감한 정보를 넣지 않도록 한다.
2. 토큰의 길이가 길어지면 네트워크에 부하를 준다.
- 토큰에 저장하는 정보의 양이 많아질수록 토큰의 길이가 길어진다. request를 전송할 때마다 길이가 긴 토큰을 보낸다면 네트워크에 부하가 증가하게 된다.
3. 토큰은 자동으로 삭제되지 않는다.
- 한 번 생성된 토큰은 자동 삭제가 되지 않기 때문에 반드시 토큰 만료 시간을 추가하여 해당 시간이 지나면 토큰이 만료되어 무효화되게 만들어야 한다.
- 토큰이 탈취된 경우 토큰 기간이 만료도기 전까지는 토큰 탈취차가 해당 토큰을 마음대로 사용할 수 있기 때문에 토큰 만료시간은 되도록 짧게 설정해야 한다.
'Spring' 카테고리의 다른 글
OAuth2 동작 방식 (0) | 2023.03.28 |
---|---|
OAuth2 (0) | 2023.03.28 |
토큰 기반 자격 증명 (0) | 2023.03.20 |
Spring Security의 권한 부여 처리 흐름 (0) | 2023.03.17 |
Spring Security의 인증 처리 흐름 (0) | 2023.03.16 |