IT/Spring

JWT 로그아웃 처리

최고영회 2019. 10. 1. 13:40
728x90
반응형
SMALL

API 서버에 대한 인증을 JWT로 진행할 경우 로그아웃 처리를 어떻게 할까?

Spring Boot + Spring Security + JWT 로 API 서버를 개발중이며 로그아웃 처리가 필요했다.

쉽게 생각했고 쉽게 처리 되었다.

이 방법이 올바른 방법인지는 사실 잘 모르겠다.

1. 로그아웃 API 가 호출되면 JWT를 Redis 에 넣어둔다. 

2. Redis 에 넣을 때 expiration time 을 JWT 의 exiration time 과 current time 을 계산해서 넣는다.
 - 만료 시간이 지난 토큰값을 가지고 있을 필요 없기 때문에 redis 에서 자동 삭제되도록 한다.

3. JWT에 대한 검증을 수행하는 Filter 에서 validation이 끝나는 지점에 이미 로그아웃 처리된 토큰인지 확인한다.
 - redis server 에 해당 토큰이 있다면 로그아웃 처리된 것.

4. 이미 로그아웃 처리 된 토큰인 경우 JWT 검증 실패로 간주한다.

잘 된다.

 

소스코드를 살펴보자.

로그아웃 API - redis 에 token 값을 넣음 

@ApiOperation(value = "logout")
@ApiResponses({ @ApiResponse(code = 204, message = "success") })
@GetMapping("logout")
public ResponseEntity<String> logout(HttpServletRequest req) {
	String token = provider.extractToken(req);
	if (provider.validateToken(token)) {
		Date expirationDate = provider.getExpirationDate(token);
		redisTemplate.opsForValue().set(
				Constant.REDIS_PREFIX + token, "l", 
				expirationDate.getTime() - System.currentTimeMillis(), 
				TimeUnit.MILLISECONDS
				);
		log.info("redis value : "+redisTemplate.opsForValue().get(Constant.REDIS_PREFIX + token));
	}
	return new ResponseEntity<String>("", HttpStatus.NO_CONTENT);
}

 

Token validation method 에서 이미 로그아웃 처리된 Token 인지 검사하도록 추가 

 public boolean validateToken(String jwtToken) {
 	try {
    	Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken);
        boolean isNotExpire = claims.getBody().getExpiration().after(new Date()); 
        if (null != redisTemplate.opsForValue().get(Constant.REDIS_PREFIX + jwtToken)) {
        	log.info("이미 로그아웃 처리된 사용자");
            return false;
        }
        return isNotExpire;
	} catch (Exception e) {
    	log.info("token is not valid");
        return false;
    }
}
728x90
반응형
LIST