💻 해결
기존에는 사용자 이름을 기준으로 인증 -> 이메일 인증으로 바꿨다.
그리고 테스트 요청을 위해서header
->cookie
에 담아서 토큰 생성
JwtAuthenticationFIlter / login -> jwt생성
String email = ((UserDetailsImpl) authResult.getPrincipal()).getUser().getEmail(); // username -> email
UserRoleEnum role = ((UserDetailsImpl) authResult.getPrincipal()).getUser().getRole();
String token = jwtUtil.createToken(email, role); // username -> email
// response.addHeader(JwtUtil.AUTHORIZATION_HEADER, token); // 헤더에 담기
jwtUtil.addJwtToCookie(token, response); // 쿠키에 담기
기존에 쿠키 생성을 username 을 기반으로 jwt를 생성했기 때문에 -> 제대로 된 토큰을 생성하지 못했고, 그로인해서 인증에서 제대로 된 토큰을 받지 못했다.
- username -> email 변수 설정
- 그리고 바꾼 이메일을 createToken 메서드에 할당
- 헤더 -> 쿠키에 담기
🏃♂️
🏃♂️
🏃♂️
JwtUtil / jwt관련 util클래스
📟 기존 헤더 가져오는 코드
// ***** 이전과 바뀐 부분 헤더에서 가져오기 ******* 쿠키 배열에서 추출하는 것이아니라 헤더에서 가져와서 간결해짐
// header 에서 JWT 가져오기
public String getJwtFromHeader(HttpServletRequest request) {
String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(BEARER_PREFIX)) {
return bearerToken.substring(7);
}
return null;
}
📟 기존 > 쿠키
// HttpServletRequest 에서 Cookie Value : JWT 가져오기
public String getTokenFromRequest(HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
if(cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(AUTHORIZATION_HEADER)) {
try {
return URLDecoder.decode(cookie.getValue(), "UTF-8"); // Encode 되어 넘어간 Value 다시 Decode
} catch (UnsupportedEncodingException e) {
return null;
}
}
}
}
return null;
}
쿠키에서 제대로 받아오고 있는 인증 과정
- 기존에 헤더에서 받아오고 있었기 때문에, 유효하지 않은 토큰 -> 제대로된 검증을 하지 않았다.
JwtAuthorizationFilter / config에서 설정한 로그인 외의 대부분 인증처리
UserDetailsServiceImpl / config에서 설정한 로그인 외의 대부분 인증처리
loadUserByUsername
-> findByUsername -> findByEmail 로 변경
- 유저네임과 이메일(요청)을 비교하고 있었으니 , 항상 유효하지 않은 토큰이 나온다.
- 인증객체를 생성할 때 이메일을 기반으로 생성해야 했다. (이름이라면 유저네임)
UserDetailsServiceImpl / UserDetailsImpl 두 개의 활용
UserDetails
:
이 인터페이스는 Spring Security에서 사용자의 인증 정보를 나타내기 위해 사용됩니다.
일반적으로 UserDetails를 구현하는 클래스 (UserDetailsImpl 같은)는 사용자의 username, password, 권한, 계정의 상태 정보 (계정 잠금, 만료 등)와 같은 세부 정보를 포함합니다.
UserDetails 인터페이스는 사용자의 인증에 필요한 정보만을 정의하며, 실제 데이터베이스와의 상호작용 또는 사용자 정보를 어떻게 조회할지에 대한 로직은 포함하지 않습니다.
UserDetailsService
:
이 인터페이스는 UserDetails 객체를 로드하는데 사용됩니다.
주요 메서드는 loadUserByUsername(String username)이며, 주어진 username에 해당하는 사용자의 인증 정보를 UserDetails 객체로 반환합니다.
UserDetailsService를 구현하는 클래스 (UserDetailsServiceImpl 같은)는 일반적으로 데이터베이스나 다른 저장소에서 사용자 정보를 조회하고 해당 정보를 바탕으로 UserDetails 객체를 생성하고 반환하는 로직을 포함합니다.
요약하면,