-
JWT 인증 방식Develop/Spring 2022. 11. 18. 11:13

JWT 란?
- JSON Web Token(JWT)의 약어로 인증에 필요한 정보들을 담은 JSON 형태의 토큰
- 클라이언트와 서버 사이 통신 시 권한 인가(Authorization)를 위해 사용
- JSON 데이터를 Base64 URL Encode를 통해 인코딩하여 직렬화
- JWT토큰(Access Token)을 HTTP 헤더에 담아서 서버가 클라이언트를 식별하기 때문에 민감 정보를 토큰 안에 넣게 된다면 위험
JWT의 구조

- Header: 토큰의 타입(typ)이나, 알고리즘(alg)을 저장
- Payload: 토큰에서 사용할 정보의 조각(Claim) 저장 (실제 JWT 를 통해서 알 수 있는 데이터)
- iat : 토큰 발급시간
- exp: 토큰 만료 시간
- Signature: 서버에서 해당 토큰이 유효한지 아닌지를 구분 할 수 있는 역할을 수행
- 헤더와 페이로드 값을 Base64로 인코딩을 하고, 헤더에서 정의한 알고리즘으로 해싱하여 다시 base64로 인코딩하여 생성
JWT의 인증 과정

JWT의 장단점
장점
- Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조 방지
- 세션(Session)방식과 다르게, 별도의 저장소가 없어서 서버 확장성이 우수(Stateless)
- 모바일 어플리케이션 환경에서도 잘 동작(모바일은 세션 사용 불가능)
단점
- Token의 Payload에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나면 네트워크 부하(트래픽 부하)
- Token을 클라이언트 측에서 관리하고 저장하기 때문에 토큰 자체를 탈취당하면 대처하기가 어려움(서버에서 관리할 수 없음)
- 기존에 생성된 JWT토큰은 수정 및 삭제 불가
Spring에서 JWT 토큰 사용
1. 로그인 시 JWT 토큰 발급

- 로그인 시 우선 이메일(ID), 패스워드 확인하는 과정을 수행
- 해당하는 유저가 존재하면 JWT 토큰(AccessToken, RefreshToken)을 생성
- 생성한 토큰들을 TokenResponseDTO객체에 담아서 클라이언트에 응답
2. JWT 토큰 발급 내부 구현

- jjwt 라이브러리를 통해 claim에 username을 설정하고 발행(iat), 만료시간(exp) 설정하고 JWT 토큰 생성
3. Response 결과

JWT 토큰으로 API 요청 수행
1. 헤더에 JWT 토큰 추가

2. Filter를 통해 API 요청 마다 JWT토큰 검증

- getToken()으로 헤더에서 Token 꺼내서 저장
- Token값이 있으면 복호화하여 유효한 Token인지 검증
- 스프링 시큐리티가 Filtering 할 수 있도록 SecurityContextHolder에 저장하고 다음 작업으로 전달
3. JWT 토큰 복호화 내부

- 서버 비밀키를 통해 복호화 수행 하여 Claim 정보 확인
- 값이 조작된 정보나 만료(Expired)된 Token 일 때는 예외(Exception)를 발생 시킨다.
4. Response 결과
성공
{ "success": true, "message": null }실패
{ "success": false, "message": "Full authentication is required to access this resource" }결론
- JWT 토큰은 장단점이 존재하기 때문에 완벽한 인증 기술 방식이 아니다.
- JWT 토큰 과 세션 저장 방식의 장단점을 잘 고려하여 개발하는 서비스에 유리한 인증 방식으로 설계해야 한다.
참고
- https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC
- https://jwt.io/