Closed f1v3-dev closed 2 months ago
아무래도 헤더 값을 받아오지 못하는것 같습니다. check-auth는 헤더를 기준으로 하는데 그 과정에서 문제가 생긴 듯 합니다. 이에 대해 좀 더 살펴볼 필요가 있을거 같네요.
제가 아까 파악했을 때 302 REDIRECT 과정에서 Authorization header에 담겨서 오더라구요? 그러다 보니까 오류가 발생한걸까요??
현재 배포된 서버에서 크롬 개발자 도구(F12)에서 네트워크쪽 켜놓은 상태에서 로그인 진행해보시면 어떤 요청이 오고갔는지 볼 수 있고 검색 (Ctrl + F)하면 refresh token과 authorization header가 어디서 나오는지 파악이 가능하니까 해당 사항 참고해서 같이 봐봅시다 !
해결 방법을 찾은 것 같습니다.
@GetMapping("/user-info")
public ResponseEntity<MemberRequestDto> getUserInfo(@CookieValue("access_token") String accessToken) {
return ResponseEntity.ok(memberService.findByAccessToken(accessToken));
}
public MemberRequestDto findByAccessToken(String accessToken) {
// String userId = SecurityContextHolder.getContext().getAuthentication().getName();
// 이게 제일 확실하긴 한데 인증되지 않은 경로로 가면 annoymousUser라고 뜨더라고요...
String userId = jwtProvider.validate(accessToken);
log.info("userId = {}", userId);
Member member = memberRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException("유저를 찾을 수 없습니다."));
log.info("member = {}", member.getNickname());
return new MemberRequestDto(member);
}
SuccessHandler에서 프론트엔드로 리다이렉트를 하지 않고 위의 엔드포인트로 리다이렉트합니다. 이때 쿠키가 설정되어야 합니다. (헤더는 값을 보내지 못합니다...)
Cookie accessTokenCookie = new Cookie("access_token", accessToken);
accessTokenCookie.setSecure(true);
accessTokenCookie.setHttpOnly(true);
accessTokenCookie.setPath("/"); // 모든 경로에서 접근 가능하도록 설정
accessTokenCookie.setMaxAge(60 * 60 * 24); // 1일
// Refresh Token 쿠키 설정
Cookie refreshTokenCookie = new Cookie("refresh_token", refreshToken);
refreshTokenCookie.setSecure(true);
refreshTokenCookie.setHttpOnly(true);
refreshTokenCookie.setPath("/"); // 모든 경로에서 접근 가능하도록 설정
refreshTokenCookie.setMaxAge(60 * 60 * 24 * 7); // 1주일
// 쿠키 추가
response.addCookie(accessTokenCookie);
response.addCookie(refreshTokenCookie);
response.sendRedirect("/Member/user-info");
전체적인 흐름을 알려주실 수 있나요?
클라이언트에서 로그인 요청을 받으면 백엔드 쪽에서 어떻게 하는건지 잘 이해가 안되네요
클라이언트에게 직접 유저에 대한 정보를 바로 준다는 말인가요?
그런...셈이긴 해요 DTO로 조정이 가능하긴 한데. 더 좋은 방법이 있을까요? Token을 쿠키로 주지 말고 SecurityContextHolder.getContext().getAuthentication().getName();를 통해 하는방법도 있어요.
프론트쪽에 회원에 관한 정보보다는 Access Token, Refresh Token을 보내주는게 맞는 것 같아요
현재 API를 호출할 때에도 Filter를 통해서 Header에 값이 있는지 파악하고, ContextHolder에 넣어주는 작업을 해놨는데 이걸 또 변경하게 되면 너무 많은 수정이 필요해보입니다..
Front 쪽으로 Access Token 값을 response body에 담아서 보내거나, 짧은 시간동안 유지되는 Cookie에 담아서 보내는게 가장 좋지 않을까요?
그것도 좋을것 같긴 하네요. 좀 더 찾아봐야 할듯?
생각했던 전체 흐름입니다
위의 방식으로 결정
🚨 어떤 버그인가요?
WHITE LIST에 등록되어있지 않은 API를 테스트하기 위해서 로그인을 진행해보았습니다.
카카오를 통해 정상적으로 회원 등록이 되어 DB에 저장되고 Refresh Token도 발급되어 Cookie에 저장이 되어있습니다. 또한 응답 헤더에 Authorization에 Bearer 형태로 넘어오는 것 까지 확인을 했어요!
현재 상황에서 정상적으로 로그인이 완료가 된 것인데 저렇게 오류 페이지로 넘어가는 이유가 무엇일까요?
💥 어떤 상황에서 발생한 버그인가요?
💡 예상 결과
로그인 -> 로그인 성공 (응답 헤더에 Bearer 형태의 Access Token, 쿠키에 Refresh Token) -> 메인 페이지로 이동