다음과 같이 에러가 나옵니다 "{"error":"invalid_request","error_description":"An authorization code must be supplied.","error_code":"KOE320"}"

문의 시, 사용하시는 개발환경과 디벨로퍼스 앱ID를 알려주세요.
___앱 ID : 1065736

db 저장은 되는데 프론트 화면이 안넘어가네요…

아래 내용 참고해주세요.

KOE320 (An authorization code must be supplied, authorization code not found) 에러가 발생할 때

인가코드 중복은 아니고 토큰도 발급되는거 같은데 페이지가 안넘어가고 Enter KaKao Code 팝업창 나옵니다… 프론트 쪽 코드의 문제일까요?

'Enter KaKao Code 팝업창 '은 카카오에서 제공하는 기능이 아닌데요.

확인 가능한 URL알려주시거나 화면 캡쳐 해주시겠어요?


앗 죄송합니다 팝업창은 제 프론트에서 만든것 같네요
로그인버튼을 누르면 새창에서 로그인 진행하는데 오른쪽 화면처럼 결과가 나옵니다. 이제 왼쪽 화면에서 submit누르면 위의오류가 나오네요…

네, 해당 화면을 어떤로직으로 띄우는지 알 수 없는데요.
오른쪽화면의 결과도 카카오가 제공하는 메시지가 아니라 개발하신 로직 확인해보셔야할 것 같습니다.
관련 코드블럭 공유해주시면 어떤 상황인지 확인해보겠습니다.

컨트롤러는 이렇구요

@GetMapping("/api/oauth/kakao/callback")
public ResponseEntity<String> login(@RequestParam String code, HttpServletRequest httpServletRequest){
    
    OauthToken oauthToken = memberService.requestToken(code);
    KakaoProfile kakaoProfile = memberService.requestKakaoProfile(oauthToken);

    Optional<Member> optionalMember = memberService.findMemberById(kakaoProfile.getId());
    if (optionalMember.isPresent()) {
        Member existingMember = optionalMember.get();
        memberService.sessionSave(httpServletRequest, existingMember, oauthToken);
        return ResponseEntity.status(HttpStatus.OK).body("Logged-in");
    } else {
        Member newMember = new Member(
                ROLE_USER,
                kakaoProfile.getKakao_account().getProfile().getProfile_image_url(),
                kakaoProfile.getId().toString(),
                kakaoProfile.getKakao_account().getProfile().getNickname());

        memberService.addMember(newMember);
        memberService.sessionSave(httpServletRequest, newMember, oauthToken);

        return ResponseEntity.status(HttpStatus.OK).body("new-member");
    }
}

리쿼스트토큰 메서드는 이렇습니다

 public OauthToken requestToken(String code) {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("grant_type","authorization_code");
    params.add("client_id","1111111");
    params.add("redirect_uri","http://localhost:8080/api/oauth/kakao/callback");
    params.add("code",code);

   
    HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);

    ResponseEntity<String> response = restTemplate.exchange(
            "https://kauth.kakao.com/oauth/token",
            HttpMethod.POST,
            kakaoTokenRequest,
            String.class
    );

    try {
        return objectMapper.readValue(response.getBody(), OauthToken.class);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }
}

인가코드가 잘 전달되는거 같은데… 다른게 문제일까요?

로그를 보니
리다이렉트 URI 등록안해서 발생한 KOE006에러는 해결하신듯하고

/api/oauth/kakao/callback에서 새로고침 하셨는지
인가코드로 액세스 토큰을 잘 받았으나 동일한 인가코드 액세스 토큰 다시 발급하려 해서 KOE320에러가 다수보이고

가입후, new-member 출력하고 끝인 것으로 보이는데요.

프론트로 넘기는 로직이 어디에 있나요?

class _LoginState extends State<Login> {
Future<void> _loginWithKakao(BuildContext context) async {
const String kakaoUrl =
    'https://kauth.kakao.com/oauth/authorize?client_id=c33ec31ce21c44a27c43a6165664cb5a&redirect_uri=http://localhost:8080/oauth/api/kakao/callback&response_ty pe=code';
 final Uri url = Uri.parse(kakaoUrl);

print('Attempting to launch: $kakaoUrl');

try {
  await launchUrl(url, mode: LaunchMode.externalApplication);
  print('Launched URL');

  // 콜백 URL에서 code를 받아오는 로직 추가 필요 (예: WebView 콜백 처리)
  // 여기서는 임시로 수동으로 코드 입력을 요청합니다.
  final code = await _getCodeFromUser(context);
  print('Received code: $code');

  // 받아온 code를 사용하여 API 호출
  final response = await http.get(
    Uri.parse('http://localhost:8080/api/oauth/kakao/callback?code=$code'),
  );

  print('API call response: ${response.statusCode}');
  print('API call response body: ${response.body}');

  if (response.statusCode == 200) {
    // 응답 성공 시 Main 페이지로 이동
    print('Login successful, navigating to Main page');
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const Main()),
    );
  } else {
    // 에러 처리
    print('Failed to login with Kakao: ${response.statusCode}');
  }
} catch (e) {
  print('Could not launch $kakaoUrl: $e');
}

}
프론트 쪽 코드인데요 인가코드를 수동으로 받게되어있습니다. 이게 잘못된거 같은데 일단 수동으로 입력하니 처음보내주신 링크에서 두번째 오류가 나오네요. 안되는게 정상인것일까요?

윗 답변 감사합니다… 프론트로 인가코드가 아닌 토큰을 보통 넘겨주는게 맞을까요?

아래 예제 참고 부탁드려요.
인카코드나 액세스토큰을 Front에 전달하지 않고 처리 결과만 전달하시면 좋을 것 같습니다.

[rest api 예제] java (spring boot) - 카카오 로그인, 카카오 친구목록 조회, 메시지 발송