JWT로 로그인한 경우에 사용자의 정보를 가져와 Controller에서 사용해야하는 상황이 있다.
JWT 토큰을 생성하는 코드에서 Claims 에 넣은 정보를 현재 토큰에서 추출하는 방법으로 구현할 수 있는데, 이를 코드로 정리해보려 한다.
내가 만든 서비스에서는 사용자가 이메일과 패스워드를 입력하여 로그인하는 방식으로 구현되어있다. 사용자의 이메일을 JWT 에서 추출해 현재 로그인된 사용자 객체 Member
을 가져오는 예제를 보여주도록 하겠다.
JwtUtil createToken 메소드
public static String createToken(String mail, String key, long expireTimeMs) {
Claims claims = Jwts.claims();
claims.put("mail", mail);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expireTimeMs))
.signWith(SignatureAlgorithm.HS256, key)
.compact();
}
Claims
에 mail
이라는 이름으로 사용자의 메일 주소 정보를 넣었다.
이는 실제로 로그인 시 사용자의 메일을 기반으로 토큰이 생성되기 때문에 JWT 에는 사용자의 메일 주소가 들어있음을 알 수 있다.
LoginService
public String login(LoginDTO loginDTO) {
Member member = memberRepository.findByMail(loginDTO.getMail())
.orElseThrow(() -> new AppException(ErrorCode.MEMBER_NOT_FOUND));
if (bCryptPasswordEncoder.matches(loginDTO.getPassword(), member.getPassword())) {
String token = JwtTokenUtil.createToken(member.getMail(), key, expireTimeMs);
return token;
} else {
throw new AppException(ErrorCode.INVALID_PASSWORD);
}
}
MemberController
@GetMapping("/get-current-member")
public Long getCurrentMember(Authentication authentication){
log.info("authentication.getName() : " + authentication.getName());
Member member = memberService.getMember(authentication.getName());
return member.getId();
}
MemberController
에 위와 같이 현재 로그인된 사용자 정보를 가져오는 메소드를 작성하였다. 파라미터에는 Authentication
을 가져와, SecurityContextHolder
에게 자동으로 Authentication
객체를 파라미터로 설정하도록 하였다.
authentication.getName()을 실행하면 초기에 Claims에 넣었던 사용자의 메일이 반환된다.
MemberService
public Member getMember(String mail) {
Member member = memberRepository.findByMail(mail)
.orElseThrow(() -> new AppException(ErrorCode.MEMBER_NOT_FOUND));
return member;
}
getMember
메소드는 서비스단에서 구현하였는데, Repository에서 Mail
필드가 일치하는 DB의 튜플을 가져오도록 하였다.
'Framework > Spring' 카테고리의 다른 글
[SpringBoot] @RedisHash를 이용한 Spring Data Redis Repository 적용기 (0) | 2023.10.07 |
---|---|
[SCG] Spring Cloud Gateway는 왜 Netty 기반으로 만들어졌을까? 그리고 WebFlux란? (0) | 2023.07.11 |
[SpringSecurity] JWT (Json Web Token) 기반의 인증 인가 구현하기 (0) | 2023.07.09 |
[3주차] Spring Security 구글 소셜 로그인 구현, 세션 관리 (0) | 2022.05.22 |
[2주차] Mustache를 이용한 게시글 CRUD 화면 및 기능 구현 (0) | 2022.05.15 |