카카오 로그인 시 401 Unauthorized: "{"msg":"this access token does not exist","code":-401}" 발생

개발환경 : 자바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<>() {
			});
	}

}

(1) {“error”:“invalid_grant”,“error_description”:“Redirect URI mismatch.”,“error_code”:“KOE303”}
인가코드에 설정한 리다이렉트 URI와 액세스 토큰 발급에 설정한 리다이렉트 URI가 달라서 오류발생했습니다.

인가코드: null
접근토큰: http://localhost:8080/api/v1/auth/login

(2) {“error”:“invalid_grant”,“error_description”:“authorization code not found for code=t_-PmAZUKXV2fVbWMTN5Sfeo2XvwnBrCKT3XwKf_g0sWGyQCB6w-v5Ok5AwKKwynAAABi-62n-7C3p98Pd5TpQ”,“error_code”:“KOE320”}

이미 액세스 토큰 발급에 사용한 인가코드로 또한번 액세스 토큰 발급 요청해서 오류발생했습니다.

(3) 401 Unauthorized: "{“msg”:“this access token does not exist”,“code”:-401}

위 에러는 액세스 토큰 발급 받을때 발생하는 에러가 아니라 액세스 토큰을 이용하여 정보조회시 잘못된 액세스 토큰을 사용했을때 발생합니다.

리다이렉트 URI에서 액세스 토큰 발급 요청 시, 응답 로깅하셔서 원인파악해보시면 좋을 것같습니다.