blog.ull.im/engineering/2019/02/07/jwt-strategy.html
위의 블로그에서 토큰 방식의 종류와 장단점 등을 자세하게 설명하고 있다.
기존 SSHJ는 웹과 앱에서 모두 Accesstoken + RefreshToken을 사용하였다. 대신 RefreshToken의 Payload에는 아무것도 담겨있지 않고 이를 Redis에 Key를 로그인 한 유저의 고유 ID로 하여 저장하였다. 이를 통해 재발급 요청이 오면 함께 받은 AccessToken에서 고유 ID를 추출하여 서버에 저장된 RefreshToken을 찾게 된다.
짧은 AccessToken의 만료 기간 덕분에 토큰이 탈취당하더라도 30분 동안만 접근이 가능하여 보안을 강화시켰다. 또한 사용자가 로그인을 매 서비스 사용 시마다 하지 않아도 되고 RefreshToken 만료 기간동안 자동로그인이 가능하다.
대신 클라이언트가 토큰 재발급 요청 시 보낸 RefreshToken이 유효한지 검사하기 위해 따로 저장공간이 필요하다. 또한 로그아웃 시 아직 만료기한을 넘기지 않은 AccessToken을 무효로 만들기 위해 '블랙리스트'로 부르는 저장공간이 따로 필요하다.
하지만 현재는 SSHJ는 웹과 앱에서의 토큰 방식을 다르게 사용하고 있다.
앱에서는 accesstoken만 쓰는 방법을 택했다. 프론트가 토큰 전달식은 처음이라 만료기한 조작에 어려움이 있어, 매 요청마다 retoken을 요청하고 이로 인해 생기는 cost가 어마무시하다. 그래서 카카오와 네이버, 구글의 소셜 로그인 api 분석 결과 RefreshToken을 쓰지 않거나 만료기한을 무한으로 설정하여 쓰는 경우도 있었다. 또한 토큰 탈취의 위험성 때문에 쓰는 이유도 있었는데 앱에서의 토큰 사용 시 탈취는 불가능하다 하여 RefreshToken을 쓰지 않고 AccessToken의 만료기한을 크게 늘리기로 결정했다.
1
2
3
4
5
6
7
8
|
Map<String, String> token = new HashMap<>();
String access_token = jwtTokenProvider.createAccessToken(userDto.getUsername(), userDto.getUserId(), userDto.getNickname(), userDto.getRole());
// String refresh_token = jwtTokenProvider.createRefreshToken();
token.put("accessToken", access_token);
// token.put("refreshToken", refresh_token);
// redisTemplate.opsForValue().set(userDto.getUsername(), refresh_token); // refresh_token은 따로 redis에 저장
return new ResponseEntity<>(token, HttpStatus.OK);
|
cs |
아직 웹에서의 토큰 사용 방식을 결정하지 못했다. 예전처럼 AccessToken + RefreshToken을 계속 사용할 지, Sliding방식을 통해 RefreshToken의 만료기한을 늘리게 할지 고민 중이다.
'Spring Boot' 카테고리의 다른 글
searching for @size: false log (0) | 2020.12.03 |
---|---|
WEB SOKCET vs REST API 차이 (0) | 2020.11.12 |
0. 스프링 부트는 스프링과 어떻게 다를까? (0) | 2020.11.08 |
1. 로그인은 어떤 방식을 써야할까? (0) | 2020.11.07 |
Redis - Can't start Redis Server (0) | 2020.09.20 |