📌 글에서 사용한 코드 : 깃헙
이번 글에서는 지난 글들에 이어서 Spring authorization server를 활용한 인증 서버 구축에 대한 이야기를 해보겠다.
그 중에서도, AccessToken에 원하는 값을 추가하는 방법에 대해서 알아보도록 하겠다.
아무런 커스터마이징 없이, 로그인 절차를 통해서 얻은 AccessToken을 jwt.io에서 파싱해보면 이런 결과를 얻을 수 있을 것이다.
유저를 특정할 수 있는 값은 sub (username)
정도가 있다.
이 값에 유저의 Id와 Role(권한)에 대한 값을 추가해보겠다.
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer(UserDetailsService userDetailsService) {
return (context) -> {
OAuth2TokenType tokenType = context.getTokenType();
if (OAuth2TokenType.ACCESS_TOKEN.equals(tokenType)) {
String username = context.getPrincipal().getName();
User user = (User) userDetailsService.loadUserByUsername(username);
List<Authority> authorities = user.getAuthorities();
context.getClaims().claims((claims) -> {
claims.put("id", user.getId().intValue());
claims.put("authorities", authorities.stream().map(Authority::getAuthority).collect(Collectors.toList()));
});
}
};
}
위와 같이 Bean을 생성해주면, 기본적으로 제공되는 JWT형식에서 원하는 값들을 claim에 추가할 수 있다.
나는 지난 글에서 UserDetails
를 상속한 User
라는 클래스를 만들었고, User
에서 id
와 authorities
를 가져와서 토큰에 추가해주었다.
이렇게하면, 자원서버에서 AccessToken을 받았을 때, 유저의 id와 권한을 바로알 수 있어서 다양한 처리가 가능해진다.
📌 Long타입은 내부적으로 파싱을 못해서 User id와 같은 Long타입 데이터는 Integer값으로 변환해주어야한다.
📌 실무에서는 User의 id를 숫자로 JWT에 찍는 건 보안상 위험할 수 있어서, 다른 고유값을 추가하거나 UUID와 같은 임의의 문자열로 User의 id를 지정하는 게 좋다.
커스텀한 후, 로그인절차를 통해서 AccessToken을 얻고, 파싱해보면 이렇게 id와 authorities가 잘 추가된 것을 확인할 수 있다.