Skip to content

Conversation

@nayonsoso
Copy link
Collaborator

@nayonsoso nayonsoso commented Feb 14, 2025

관련 이슈

작업 내용

문제 내용

로그아웃에서 예외가 발생했습니다.

argument type mismatch
Controller [com.example.solidconnection.auth.controller.AuthController]
Method [public org.springframework.http.ResponseEntity<java.lang.Void> 
com.example.solidconnection.auth.controller.AuthController.signOut(com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication)] with argument values:

 [0] [type=com.example.solidconnection.custom.security.authentication.SiteUserAuthentication] 
[value=SiteUserAuthentication 
[Principal=com.example.solidconnection.custom.security.userdetails.SiteUserDetails@16a8d604, Credentials=
[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[ROLE_MENTEE]]]

로그아웃 컨트롤러에서 ExpiredTokenAuthentication 을 기대했는데 그건 없고,
SiteUserAuthentication 가 있다는 내용의 예외입니다.

문제 원인

제가 시큐리티를 구성할 때, 잘못 생각했던 부분이 있었습니다.
저는 로그아웃 api 엑세스 토큰 재발급 api 에 있는
토큰이 만료되었더라도 요청을 받아야 한다, 그리고 서비스 코드까지 토큰을 넘겨줘야 한다
라는 특수한 요구사항을 만족시키기 위해서, ExpiredToken 이라는 개념을 만들어줬습니다.

그런데 코드 상에서 문제가 되었던 부분은,

  • JwtFilter에서 만료된 토큰이면 ExpiredTokenAuthentication 를 context에 저장하고
  • 로그아웃 api 와 엑세스 토큰 재발급 api의 컨트롤러에서 ExpiredTokenAuthentication 을 인자로 받았던 부분

입니다.

이렇게 하니 “로그인했으며, 토큰이 만료되지 않은 사용자”는 가 저 api 를 호출할 때 문제가 발생했습니다.
토큰이 만료되지 않았으니 JwtFilter에서 ExpiredTokenAuthentication가 아니라 SiteUserAuthentication 을 발급했고,
그랬기 때문에 컨트롤러의 인자로 ExpiredTokenAuthentication 를 받지 못했습니다…

문제 해결

그래서 ExpiredTokenAuthentication 이라는 개념을 없애고,
당장 컨트롤러에서는 Authentication 으로부터 바로 토큰을 받아오도록 수정해뒀습니다.
ExpiredTokenAuthentication 을 변경하고 시큐리티 구조를 다시 생각하는건 더 시간이 걸릴 것 같아 fix 용도의 PR 만 따로 올립니다.


문제 내용

미인증 상태로 마이페이지 접근시 예외가 발생했습니다

Cannot invoke "com.example.solidconnection.siteuser.domain.SiteUser.getId()" because "siteUser" is null

문제 원인

기존에는 리졸버에서 일치하는 정보가 없으면 null 을 반환하게 했습니다.
받아서 사용하는 쪽에서 예외를 발생시키는게 맞다고 생각했습니다.
하지만 이렇게 처리하니 SiteUser 에서 바로 값을 꺼내오기 위해 getter 함수를 호출할 경우 NPE 가 발생하는 문제가 발생했습니다.

문제 해결

이를 어노테이션의 required 를 통해 해결했습니다.
기본적으로 required = true 로 하고 리졸버 단에서 required = true 임에도 정보가 없으면 401 예외가 발생하게 구현했습니다.
회원/비회원이 모두 사용할 수 있는 맞춤 대학 추천은 required = false 를 걸어줬습니다.

특이 사항

리뷰 요구사항 (선택)

@nayonsoso nayonsoso changed the title Fix/200 controller auth parameter require fix: 인증과 관련되어 리졸버와 컨트롤러 인자에서 발생한 이슈 해결 Feb 14, 2025
Comment on lines 95 to 104
@PostMapping("/sign-out")
public ResponseEntity<Void> signOut(
@ExpiredToken ExpiredTokenAuthentication expiredToken
Authentication authentication
) {
authService.signOut(expiredToken.getToken());
String token = authentication.getCredentials().toString();
if (token == null) {
throw new CustomException(ErrorCode.AUTHENTICATION_FAILED, "토큰이 없습니다.");
}
authService.signOut(token);
return ResponseEntity.ok().build();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JwtAuthetication 에서 credential 로 토큰 자체를 저장하게 해서
컨트롤러에서 인자로 쉽게 가져올 수 있었습니다~

Comment on lines +3 to 4
// todo: 사용되지 않음, 다른 PR에서 삭제하고 더 효율적인 구조를 고민해봐야 함
public class ExpiredTokenAuthentication extends JwtAuthentication {
Copy link
Collaborator Author

@nayonsoso nayonsoso Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 좀 고민이 필요할 것 같아서.. 😭 일단 fix PR만 먼저 올립니다!

@nayonsoso nayonsoso added the 버그 Something isn't working label Feb 14, 2025
Copy link
Contributor

@Gyuhyeok99 Gyuhyeok99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

@nayonsoso nayonsoso merged commit ea76630 into solid-connection:main Feb 14, 2025
@nayonsoso nayonsoso self-assigned this Feb 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

버그 Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants