728x90
토큰 기반 인증
토큰 기반 인증?
대표적인 사용자 인증 확인 방법
- 서버 기반 인증
- 토큰기반 인증
토큰 기반 인증
토큰을 사용하는 방법. 토큰은 서버에서 클라이언트를 구분하기 위한 유일한 값이다. 서버가 토큰을 생성해서 클라이언트에게 제공하면 클라이언틑는 이 토큰을 가지고 있다가 여러 요청을 이 토큰과 함께 신청한다. 서버는 토큰만 보고 유효한 사용자인지 검증한다.토큰을 전달하고 인증받는 과정
- 클라이언트가 아이디와 비밀번호를 서버에게 전달하면서 인증을 요청
- 서버는 아이디와 비밀번호를 확인해 유효한 사용자인지 검증, 유효한 사용자이면 토큰을 생성해서 응답
- 클라이언트는 서버에서 준 토큰을 저장
- 이후 인증이 필요한 API를 사용할 때 토큰을 함께 보냄
- 서버는 토큰이 유효한지 검증
- 토큰이 유효하다면 클라이언트가 요청한 내용 처리
토큰 기반 인증의 특징
- 무상태성
- 확장성
- 무결성
무상태성
무상태성은 사용자의 인증 정보가 담겨 있는 토큰이 서버가 아닌 클라이언트에 있으므로 서버에 저장할 필요가 없음(서버가 뭔가 데이터를 유지하고 있으려면 그만큼 자원을 소비해야한다)상태관리
클라이언트에서 인증정보가 담긴 토큰을 생성사고 인증하는데 이때 사용자의 상태를 유지하면서 이후 요청을 처리하는 것을 상태를 관리한다라고 말한다.결론
서버는 무상태(클라이언트의 인증 정보를 저장하거나 유지하지 않아도 된다. => 자원 소비가 없다)로 효율적인 검증이 가능하다
확장성
무상태성은 확장성에 영향을 준다 => 서버를 확장할 때 상태 관리를 신경 쓸 필요가 없어서 서버 확장에도 용이하다
예시
- 서비스 : 물건을 팜
- 결제서버
- 주문서버
세션인증기반
각각 API에서 인증을 해야함(서버에서 처리해야하기 때문에)토큰 기반 인증
토큰을 가지는 주체는 서버가 아니라 클라이언트이기 때문에 가지고 있는 하나의 토큰으로 결제 서버와 주문 서버에게 요청을 보낼 수 있다.
추가로 페이스북 로그인, 구글 로그인 같이 토큰 기반 인증을 사용하는 다른 시스템에 접근에 로그인 방식을 확장 할 수도 있고, 이를 활용해 다른 서비스에 권한을 공유 할 수도 있다.무결성
HMAC
토큰 방식은 HMAC기법이라고도 부른다. 토큰을 발급한 이후에는 토큰 정보를 변경하는 행위를 할 수 없다. 즉, 토큰의 무결성이 보장된다.
만약 누군가 토큰을 한 글자라도 변경하면 서버에서는 유효하지 않은 토큰이라고 판단한다.JWT
구조
발급반은 JWT를 이용해 인증을 하려면 HTTP 요청 헤더 중에 Authorization 키값에 Bearer + JWT 토큰값을 넣어 보내야 합니다. 이런 JWT는 - 헤더
- 내용
- 서명
으로 이루어져 있다.aaaaa//헤더 . bbbbb//내용 . ccccc//서명
헤더
토큰의 타입과 해싱 알고리즘을 지정하는 정보를 담는다{ "typ": "JWT" "alg": "HS256" }
헤더의 구성
- typ : 토큰의 타입을 지정한다. JWT라는 문자열이 들어간다
- alg : 해싱 알고리즘을 지정한다
내용
토큰과 관련된 정보를 담는다. 내용의 한 덩어리를 클레임이라고 부르며 클레임은 키값을 한 쌍으로 이루어져 있습니다. 클레임은 등록된 클레임, 공개 클레임, 비공개 클레임으로 나눌 수 있습니다.등록된 클레임
- iss : 토큰 발급자
- sub : 토큰 제목
- aud : 토큰 대상자
- exp : 토큰의 만료 시간. NumericDate 형식으로 함
- nbf : 토큰의 활성 날짜와 비슷한 개념으로 nbf는 Not Before을 의미함. NumericDate 형식으로 날짜 지정
- iat : 토큰이 발급된 시간으로 iat은 issued at을 의미한다
- jti : JWT의 고유 식별자로서 주로 일회용 토큰에 사용됨
공개 클레임
공개 클레임은 공개되어도 상관없는 클레임을 의미한다. 충돌을 방지할 수 있는 이름을 가져야 하며, 보통 클레임 이름을 URI로 짓는다.비공개 클레임
공개되면 안되는 클레임. 클라이언트와 서버 간의 통신에 사용된다.{ "iss": "ajufresh@gmail.com", // JWT 자체에서 등록된 클레임 "iat": 1622370878, // JWT 자체에서 등록된 클레임 "exp": 1622372678, // JWT 자체에서 등록된 클레임 "https://codebene.com/jwt_claims/is_admin": true, // 공개 클레임 "email": "dev.rowoon@gmail.com", // 비공개 클레임 "hello": "안녕하세요!" // 비공개 클레임 }
서명
해당 토큰이 조작되었거나 변경되지 않았음을 확인하는 용도로 사용하며, 헤더의 인코딩 값과 내용의 인코딩 값을 합친 후에 주어진 비밀키를 사용해 해시값을 생성합니다.토큰 유효기간
토큰 자체가 노출되면 어떻게 될까?
토큰은 이미 발급되면 그 자체로 인증 수단이 되므로 서버는 토큰과 함께 들어온 요청이 토큰을 탈취한 사람의 요청인지 확인할 수 없다.리프레시 토큰
토큰 유효기간 하루 -> 하루동안 뭔가 할 수 있다 -> 토큰 유효기간이 짧으면 됨. -> 사용자 입장에선 불편함 -> 리프레시 토큰!!
리프레시 토큰은 엑세스 토큰과 별개의 토큰이다 사용자를 인증하기 위한 용도가 아니라 엑세스 토큰이 만료되었을때 새로운 엑세스 토큰을 발급하기 위해 사용한다. 엑세스 토큰의 유효기간을 짧게 설정하고 리프레시 토큰의 유효 기간을 길게 설정하면 공격자가 엑세스 토큰을 탈취해도 몇 분 뒤에는 사용할 수 없는 토큰이 되기 때문에 더욱 안전!!
흐름
- 클라이언트가 서버에게 인증 요청함
- 서버는 클라이언트에서 전달한 정보를 바탕으로 인증 정보가 유효한지 확인한 뒤, 엑세스 토큰과 리프레시 토큰을 만들어 클라이언트에게 전달. 클라이언트는 전달받은 토큰 저장
- 서버에서 생성한 리프레시 토큰은 DB에도 저장해둔다
- 인증을 필요로 하는 API를 호출할 때 클라이언트에 저장된 액세스 토큰과 함께 API 요청함
- 서버는 전달받은 액세스 토큰이 유효한지 검사한 뒤에 유효하다면 클라이언트에서 요청한 내용을 처리함
- 시간이 지나고 액세스 토큰이 만료된 뒤에 클라이언트에서 원하는 정보를 얻기 위해 서버에게 API 요청을 보냄
- 서버는 액세스 토큰이 유효한지 검사. 만료된 토큰이면 유효하지 않기 때문에 토큰이 만료되었다는 에러 전달
- 클라이언트는 이 응답을 받고 저장해둔 리프레시 토큰과 함께 새로운 엑세스 토큰을 발급하는 요청 전송
- 서버는 전닯다은 리프레시 토큰이 유효한지, DB에서 리프레시 토큰을 조회한 후 저장해둔 리프레시 토큰과 같은지 확인
- 만약 유효한 리프레시 토큰이라면 새로운 액세스 토큰을 생성한 뒤 전달
- 다시 4번과 같이 API 요청
반응형
'Spring, Spring boot' 카테고리의 다른 글
트랜잭션 (1) | 2023.10.26 |
---|---|
JPA 동작원리 (0) | 2023.10.25 |
스프링 시큐리티 (0) | 2023.10.18 |
타임리프와 템플릿 엔진 (0) | 2023.10.17 |
직렬화와 역직렬화 (0) | 2023.10.17 |