[Spring Security] JSON Web Token(JWT)

Barded·2023년 2월 24일

Spring Security

목록 보기
2/4
post-thumbnail

JSON Web Token(JWT)

JWT란?

JSON Web Token(JWT)은 토큰 기반의 인증이다.

  • 클라이언트가 아이디와 비밀번호를 서버에게 전달하여 인증을 요청한다.
  • 서버는 아이디와 비밀번호를 통해 인증하여 유효한지 확인하고, 유효한 경우 토큰을 생성해서 응답한다.
  • 클라이언트는 토큰을 저장해 두었다가 인증이 필요한 api요청에 토큰 정보와 함께 요청한다.
  • 서버는 토큰이 유효한지 검증하고, 유효한 경우 응답을 한다.

JWT의 특징은 아래와 같다.

  1. Stateless(무상태성) - 사용자의 인증정보가 담겨있는 토큰을 클라이언트 서버에서 저장하기 때문에 서버는 완전한 무상태를 가질 수 있다. 이로 인해 서버를 확장할 떄 용이하다.
  2. Scalability(확장성) - 토큰 기반 인증을 사용하는 다른 서비스에 접근이 가능하다.
  3. Integrity(무결성) - 발급 후의 토큰 정보를 변경하는 행위가 불가능하며, 변조될 시 바로 알아채릴 수 있다.

JWT는 header - payload - signature로 이루어져 있다.

  1. header
    헤더는 토큰의 타입과 해싱 알고리즘을 지정하는 정보를 포함한다.
{
	"type" : "JWT",
 	"type" : "HS256"
}

JWT토큰으로 이루어져 있고, HS256 알고리즘이 사용되었다는 것을 알 수 있다.

  1. payload
    토큰에 담을 정보가 들어간다. 정보의 한덩어리는 claim이라고 불리며 key-value로 구성되어 있다. 클레임은 registerted, public, private 세가지로 분류할 수 있다.
  • registered claim
    • iss : 토큰 발급자(issuer)
    • sub : 토큰 제목(subject)
    • aud : 토큰 대상자(audience)
    • exp : 토큰의 만료시간(expiraton). 시간은 NumericDate 형식으로 되어있어야 하며,(예: 1480849147370) 항상 현재 시간보다 이후로 설정되어있어야한다.
    • nbf : Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념. NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
    • iat : 토큰이 발급된 시간 (issued at)
    • jti : JWT의 고유 식별자로서, 주로 일회용 토큰에 사용한다.
  • public claim
    공개된 클레임, 충돌을 방지할 수 있는 이름을 가져야 한다.
  • private claim
    클라이언트-서버간의 통신을 위해 사용되는 클레임이다.
{
    "iss": "barded@gmail.com", // 등록된(registered) 클레임
    "iat": 1622370878, // 등록된(registered) 클레임
    "exp": 1622372678, // 등록된(registered) 클레임
    "http://velog.io/barded": true, // 공개(public) 클레임
    "email": "barded@gmail.com", // 비공개(private) 클레임
    "hello": "안녕하세요!" // 비공개(private) 클레임
}
  1. 서명
    해당 토큰이 조작되었거나 변경되지 않았을믈 확인하는 용도로 사용하며, header의 인코딩 값과 정보의 인코딩값을 합친 후에 주어진 비밀키를 통해 해쉬값을 생성한다.

JWT 사용

  1. Add build dependencies
implementaion 'io.jsonwebtoken:jjwt:0.9.1'
  1. Create JWT
public String createToken(){
	return Jwts.parserBuilder()
    	.setSubject(username)
        .setExpiration(now + expireTime)
        .signWith(secretKey, SignatureAlgorithm.HS256)
        .compact();
}
  1. Parse JWT
public String parseToken(String token){
	try{
    retrun Jwts.parser()
      .setSigningKey(secretKey)
      .parseClaimsJws(token)
      .getBody();
    } catch (JWTExcecptions e){
    	...
    }
}

JWT를 파싱하는 과정에서 발생할 수 있는 예외는 다음과 같다.

  • UnsupportedJwtException : 예상하는 형식과 다른 형식이거나 구성의 JWT일 때
  • MalformedJwtException : JWT가 올바르게 구서오디지 않았을 때
  • ExpiredJwtException : JWT를 생성할 때 지정한 유효기간이 초과되었을 때
  • SignatureException : JWT의 기존 서명을 확인하지 못했을 때
  • IllegalArgumentException

위의 예외에 대해 적절한 처리를 해주는게 좋다고 한다.

출처 : 헤어린블로그-Spring Boot에서 JWT사용하기

profile
Now or Never

0개의 댓글