HTTP stateless
- HTTP는 각 통신 상태가 저장되지 않는다.
- 따라서 일반적으로 새 페이지 요청할 때마다 로그인이 필요하다.
인증(Authentication)
- 주체(Principal)의 신원(Identity)를 증명을 검증하는 과정
- 애플리케이션에서 주체는 일반적으로 사용자이며, 사용자는 인증에 신원 증명 정보, 즉 Credential을 보낸다.
- 일반적인 사용자 Credential은 password이다.
인가(Authorization)
- 인증된 사용자에게 권한(Authority)을 줘서 애플리케이션 특정 자원에 대한 접근을 허용하는 과정
- 권한은 일반적으로 role 형태로 부여한다.
- 사용자의 role에 따라 자원에 대한 접근 제어(Access Control)이 필요하다.
세션(Session)과 토큰(Token)
- HTTP에서 동일한 사용자인데도 요청할 때마다 기억하지 못하는 문제 해결을 위해 인증에 대해 세션 또는 토큰을 부여하고, 사용자가 새로운 요청마다 해당 요청에 대한 인가(접근에 대한 허용)를 위해 세션/토큰을 보내도록 한다.
세션과 토큰의 차이점 1: 저장 위치
- 세션: 데이터베이스 서버에 저장
- 클라이언트 측에서만 저장
세션과 토큰의 차이점 2: 크기
세션과 토큰의 차이점 3: Security
- 세션
- 서버에서 저장/관리하지만 공격 위험이 있으므로 유효기간, HttpOnly, Secure 옵션 등으로 쿠키에 저장
- 토큰
- 웹 브라우저에 (local storage 또는 쿠키 등) 저장되므로 공격에 노출될 가능성이 크다.
- 토큰에는 민감한 정보 담지 않고 유효기간 짧게 설정해 공격에 노출되는 시간 최소화함
- 유효기간 짧으면 사용자가 로그인 해주는 주기가 짧아지므로 로그인, 즉 인증 시 refresh token(상대적으로 더 긴 유효기간, 안전한 곳에 저장)을 추가로 발급한다.
- 기존 토큰 만료되거나 변조될 경우 refresh token을 통해 토큰을 재발급한다.
세션과 토큰의 차이점 4: 확장성
- 대부분 웹 서비스에서 토큰 방식 사용하는 이유로, 세션은 서버에 저장되므로 다중 접속자가 많은 큰 서비스의 경우 서버 과부하가 발생할 수 있다.
- 서버 분산으로 해결할 수 있지만, 서버 분산 방식의 경우 요청이 전달된 서버에 사용자의 session 정보가 저장되지 않았으면 다시 로그인(인증)이 필요하다.
세션과 토큰의 차이점 5: 동작 방식
세션
1. 사용자는 id, password 정보와 함께 signIn 요청을 서버에 보냄
2. 서버에서 해당 사용자에 대한 session 생성 및 저장, 응답으로 cookie에 session id 전달
3. 사용자는 요청마다 쿠키 session id를 전달해서 애플리케이션 자원 접근에 대한 권한을 요청한다. (인가)
4. 서버는 사용자가 전달한 쿠키의 session 정보와 데이터베이스에 저장된 session 비교한다. 인가 성공/실패 여부를 사용자에 전달하여 응답한다.
토큰
1. 사용자는 id, password 정보와 함께 서버에 signIn 요청을 보낸다.
2. 서버는 토큰을 생성하고, 서버가 가지고 있는 secret key로 서명한다. 서버는 토큰으로 응답한다.
3. 사용자는 요청마다 토큰을 전달하여 자원 접근을 요청한다. (인가)
4. 서버는 사용자가 전달한 토큰의 서명(signature)을 서버가 가지고 있는 secret key로 풀어서(Token Decryption 알고리즘 사용) 사용자 정보를 확인하여 인가 여부를 체크한다. 서버는 인가 성공/실패 여부로 응답한다.
JWT (JSON Web Token)
- 디지털로 서명되는 JSON 객체
- 사용자는 한 번의 credential 정보(id, password 등)로 서버에 인증(authentication)으로 JWT를 발급받을 수 있다.
- 이후의 모든 요청에 사용자는 인가에 대한 인증을 위해 credential 정보 없이 JWT를 서버에 전달하면 된다.
JWT 동작 방식
- 사용자는 Header에 JWT token 적어서 모든 요청을 서버에 보낸다.
JWT 구조
- JWT 페이로드의 정보는 모두가 볼 수 있다. 따라서 JWT 페이로드에 password와 같은 민감한 credential은 담지 않는 것이 안전하다. 페이로드를 암호화하여 더 안전하게 전달할 수 있다.
JWT 생성
https://www.javainuse.com/jwtgenerator
JWT Online Token Generator를 이용해서 JWT Token을 생성할 수 있다.
토큰 생성 후 해시 알고리즘으로 서명을 한다.
JWT 확인
- 서버에서는 서명된 토큰을 secret key를 이용해서 디코딩해서 정보를 확인한다.
https://www.javainuse.com/decodeJWT
- 위의 JWT Online Decoder를 사용해서 JWT를 확인할 수 있다.