개발환경 : 자바17, 스프링부트 3.2.0-RC2
앱ID : ID 983839
https://kauth.kakao.com/oauth/authorize?client_id={rest api 앱 키}&redirect_uri={리타이렉트 주소}&response_type=code
를 호출해서 인가코드를 발급 받는 것까지는 정상 처리 되는데, 그후 인가코드로 액세스 토큰을 발급받으려고 하면 401 Unauthorized: "{“msg”:“this access token does not exist”,“code”:-401}"가 발생합니다.
아래는 토큰 발급 요청 메서드와 사용자 정보 요청 메서드가 담긴 service class입니다. 인코딩 과정 또는 헤더 설정에서 문제가 있어서 401 에러가 발생하는 건지, 아니면 다른 이유가 있는 건지 확인해주시면 감사하겠습니다.
@Service
public class AuthService {
private final InMemoryRegistrationsRepository inMemoryRegistrationsRepository;
private final UserService userService;
private final JwtService jwtService;
private final RestClient restClient;
public AuthService(InMemoryRegistrationsRepository inMemoryRegistrationsRepository, UserService userService,
JwtService jwtService) {
this.inMemoryRegistrationsRepository = inMemoryRegistrationsRepository;
this.userService = userService;
this.jwtService = jwtService;
restClient = RestClient.builder()
.build();
}
// Todo : 예외 수정
public LoginTokenResponse login(String code, String provider) {
OauthRegistration registration = inMemoryRegistrationsRepository.findByProviderName(provider);
if (registration == null) {
throw new RuntimeException();
}
OauthTokenResponse tokenResponse = requestAccessToken(code, registration);
OauthUserInfo userInfo = getUserInfo(provider, registration, tokenResponse);
UserLoginResponse loginUser = userService.oauthLogin(provider, userInfo);
return jwtService.issueTokens(loginUser.isHasLoggedInBefore(), loginUser.getUser());
}
private OauthTokenResponse requestAccessToken(String code, OauthRegistration registration) {
return restClient.post()
.uri(registration.getTokenUri())
.header("Content-type", "application/x-www-form-urlencoded;charset=utf-8")
.body(createTokenRequestParams(code, registration))
.retrieve()
.toEntity(OauthTokenResponse.class)
.getBody();
}
private MultiValueMap<String, String> createTokenRequestParams(String code, OauthRegistration registration) {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", registration.getClientId());
params.add("client_secret", registration.getClientSecret());
params.add("redirect_uri", registration.getRedirectUri());
params.add("code", code);
return params;
}
private OauthUserInfo getUserInfo(String providerName, OauthRegistration registration,
OauthTokenResponse tokenResponse) {
Map<String, Object> userAttributes = getUserAttributes(registration, tokenResponse);
return OauthUserInfo.of(providerName, userAttributes);
}
private Map<String, Object> getUserAttributes(OauthRegistration registration,
OauthTokenResponse tokenResponse) {
return restClient.get()
.uri(registration.getUserInfoUri())
.headers(header ->
header.setBearerAuth(tokenResponse.accessToken()))
.retrieve()
.body(new ParameterizedTypeReference<>() {
});
}
}