j00r6 / SPYAIR-Fansite-Project

1 stars 1 forks source link

[BE] Fix : Member #04_03 토큰 동작오류 수정, Resolver 구현 #38

Open j00r6 opened 9 months ago

j00r6 commented 9 months ago

수정내역

666247658fe3dcfc722fe5c9854b4f4735b8e288

Resolver - 토큰에서 인증된 정보가 저장된 SecurityContextHolder 에서 원하는 정보 출력하여 어노테이션으로 쉽게 활용하기 위해 구현

오류 및 해결 과정

첫번째 오류


오류내용

Resolver 구현 이후 포스트맨으로 토큰을 요청 해더값에 넣어 자체 테스트 진행중 예외 처리에 걸려서 만료된 토큰이라는 메세지를 받음

[2024-01-20 01:47:56] [INFO ] [p.b.jwt.token.TokenProvider        ] 만료된 JWT 입니다.  
[2024-01-20 01:47:56] [INFO ] [p.boardspring.jwt.token.JwtFilter  ] 유효한 JWT 이 없습니다, uri: /members/test-resolver

원인

jwt 만료시간을 설정 해놓은 파일을 확인해보니 AccessToken의 만료시간이 600으로 설정되어있었음

jwt:
  key: ${JWT_SECRET_KEY}
  access-token-expiration-minutes: 600
  refresh-token-expiration-minutes: 420

해결

만료시간 정보를 찾아보니 3600000 이 1시간으로 환산 말도안되게 짧은시간에 토큰의 만료시간이 다되어 만료되어버린것..

# JWT, 1HOUR=3600000 / 24HOUR=86400000
jwt.secret=your-secret-key
jwt.accessTokenExpirationTime=3600000
jwt.refreshTokenExpirationTime=86400000

두번째 오류


오류 내용

Resolver 구현완료후 테스트 시 anonymousUser 표출 (권한정보를 찾을수 없음)

[2024-01-20 01:47:56] [INFO ] [p.b.r.LoginUserIdArgumentResolver  ] anonymousUser principal

원인

해당 파일 : jwt.service.TokenService.class

토큰을 생성하려면 로그인 요청을 받아야하는데 로그인 요청을 받는 DTO member.DTO.LoginRequest.class 에서 로그인을 시도하는 사용자의 email(ID), password 를 전달 받는데 멍청하게 (1) 과 같이 사용한것이 원인 이었다.. 아무정보도 담겨있지 않은 (1) 으로 인해 토큰에 아무정보도 들어가지 않은것이었다..

public TokenDto login (String email, String password) { - (1)
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, password);
...
...
}

해결

올바른 값으로 변경

public TokenDto login (LoginRequest request) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword());
...
...
}

추가 내용

해당 파일 : resolver.LoginUserIdArgumentResolver

기존

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

변경

Object principal = SecurityContextHolder.getContext().getAuthentication().getName();

SecurityContextHolder.getContext().getAuthentication() 은 UserDetails 에 있는 User 혹은 CustomUserDetails 에 있는 정보를 활용하여 토큰으로 인증에 통과된 정보만 저장하고 있기때문에 .getName(); 과 같은 형식으로 CustomUserDetails 에서 원하는 정보를 가져올수 있음

.getName(); 과 같은 메서드는 토큰이 생성될때 필요한 정보를 추가하고 UserDetails 의 구현체인 CustomUserDetails 를 통해 추가 해주어야 활용 할수 있다.

해당 코드에서는 MemberService 에서 email 을 통해 회원정보를 검색하는 로직을 구현해놨기 때문에 CustomUserDetails 에서 Username 으로 설정된 email 즉, .getName() 을 통해 이메일 정보를 가져온것


테스트용 Resolver API

API : /members/test-resolver

요청

Type : Header
Key : Authorization
Value : 로그인 시 발급된 Bearer 형식의 토큰 값

응답

테스트 성공~