iOS 앱에서 카카오 로그인이 되지 않아 확인 요청드립니다

문의 시 사용하시는 SDK 버전 정보와 플랫폼(Android / iOS) 및 디벨로퍼스 앱ID를 알려주세요.


안녕하세요. 카카오톡 OAuth 연동 로그인을 이용하여 ‘어플레이즈’ 라는 앱을 운영하고 있는 개발자 입니다.

현재 iOS 앱에서만 카카오 로그인 시도 시 백엔드에서 응답을 받지 못하고 있는 상태여서 확인 요청드립니다.

아래는 앱ID와 버전 정보입니다.

앱 ID : 6446978790
sdk 버전: 1.0.8

기재하신 앱ID는 카카오 디벨로퍼스 앱ID 가아닙니다.

확인 부탁드려요.


앱ID
https://developers.kakao.com/ 의 내 애플리케이션>앱 설정>요약 정보 : 기본정보에 있는 앱 ID
숫자로된 ID 입니다~
ex) 123456

추가로 kakao_flutter_sdk에는 1.0.8 버전이 존재하지 않고, 카카오에서는 공식적으로 kakao_flutter_sdk만 개발 및 운영하고 있기 때문에 다른 SDK를 사용하고 계신다면 해당 SDK 측에 문의 부탁드립니다.

앱 ID 다시 올립니다.
앱ID : 843328

혹시 해당 앱ID를 가지고 있는 계정으로 문의를 다시 남겨야될까요?

로그상 특별한점은 없고 액세스 토큰도 정상 발급 받은 것으로 확인됩니다.

'백엔드에서 응답을 받지 못하고 있는 상태’가 어떤 것인지 구체적으로 설명해주시겠어요?

Flutter SDK 로그인 처리 부 코드 블럭도 공유 부탁드려요.

iOS앱인 경우 카카오로 로그인을 요청하는 경우 앱에서 백엔드로 신호를 보내고 있지 않고 있습니다.

앱에서 카카오로 정보 요청 시 정상적으로 값이 넘어오는지 확인하고 싶습니다.

그리고 웹에서 아이디/비번을 입력하는 경우는 로그인이 되는데 앱 to 앱으로 정보를 가져오는 경우가 문제가 되는 것 같습니다.

아래는 sdk 정보와 코드 입니다.

kakao_flutter_sdk_user: ^1.5.0

// 카카오 로그인
      else if (flag == "kakao") {
        // 카카오톡이 설치되어 있는 경우
        if (await isKakaoTalkInstalled()) {
          try {
            OAuthToken token = await UserApi.instance.loginWithKakaoTalk();
            accessToken = token.accessToken;
            refreshToken = token.refreshToken ?? '';
          } catch (error) {
            debugPrint('카카오톡으로 로그인 실패 $error');

            // 카카오톡에 연결된 카카오계정이 없는 경우, 카카오계정으로 로그인
            try {
              OAuthToken token = await UserApi.instance.loginWithKakaoAccount();
              accessToken = token.accessToken;
              refreshToken = token.refreshToken ?? '';
            } catch (error) {
              debugPrint('카카오계정으로 로그인 실패 $error');
            }
          }
        }
        // 카카오계정으로 로그인
        else {
          try {
            OAuthToken token = await UserApi.instance.loginWithKakaoAccount();
            accessToken = token.accessToken;
            refreshToken = token.refreshToken ?? '';
          } catch (error) {
            debugPrint('카카오계정으로 로그인 실패 $error');
          }
        }
      }

여기서 말씀하신 백엔드가 카카오와 무관한 개발하신 백엔드를 의미하신걸까요?

카카오측에서는 토큰 발급까지 정상 처리되었습니다.
로그인하면 catch 구문으로 떨어지나요?

개발하신 백엔드를 호출 못한다면 카카오와 무관한 내용으로 개발하신 코드를 확인해보셔야할 것 같아요.

네 백엔드는 카카오와 무관한 어플레이즈 백엔드 서버를 의미합니다.

네 확인 감사합니다.

앱 to 앱으로 로그인 시 처리가 제대로 되는지 확인해봐야될 것 같습니다.

1개의 좋아요

앱 to 앱으로 로그인 시 처리에 대해 확인 결과입니다.

loginWithKakaoTalk() 을 await 하는 중에 걸려서 넘어가지 않고, try catch 처리를 했는데도 catch로 넘어가지 않는 상황입니다.
1.4.3 ~ 1.6.1 까지 모두 동일한 상태이며, loginWithKakaoAccount() 는 문제 없이 수행됩니다.
loginWithKakaoTalk() 을 수행하는 쪽 코드와, 실행했을 때의 로그 사진 첨부합니다.

kakao login code

https://devtalk.kakao.com/t/ios/132544/11?u=saintdin

앱 to 앱으로 로그인 시 loginWithKakaoTalk() 는 카카오쪽으로 로그인을 요청하는 코드이고 이때 await에서 넘어가지 않는 상태입니다. 에러가 발생해서 catch로 빠져나가면 웹으로 로그인을 시도할텐데 catch로 빠지지않고 있습니다.

loginWithKakaoTalk() 이 sdk에서 제공되는 메소드로 알고 있는데 이 부분에 대해서 확인이 가능한가요?

안녕하세요

서버 로그를 확인했을 때 카카오톡 앱으로 전환되어 인가 코드가 정상적으로 발급된 것 확인했고, 앱으로 돌아와서 토큰 발급하는 과정에서 이슈가 있는 것으로 보입니다.

가이드 참고하셔서 제대로 설정되어있는지 확인 부탁드리고, 설정을 다 했음에도 이슈가 재현된다면 이슈 발생 영상 추가로 첨부해주시면 감사하겠습니다

info.plist 파일의 kakaokompassauth, Url schemes에는 kakao$nativeAppKey 형태로 모두 작성되어있음을 확인했고, 해당 내용 첨부파일로 공유드립니다.
아울러 요청하신 이슈 발생 영상 전달드리며, 카카오 로그인 버튼 클릭 시 로딩 인디케이터를 표시하며 관련 기능을 수행하게 되며, 일전에 공유드린 코드를 바로 수행하게 됩니다.
isKakaoTalkInstalled() 확인 → true 반환으로 loginWithKakaoTalk() 실행 → 해당 부분에서 await 이 걸려있어
기능이 더이상 수행되지 않아, 기능 수행이 종료될 시 사라지는 로딩 인디케이터가 계속 표시되는 상황입니다.

아래에 이미지와 영상 링크 첨부합니다.


https://drive.google.com/file/d/1r-2OrW-UaVf45xNkT0BXy-SY0Da-Ry0A/view?usp=drive_link

첨부해주신 영상을 확인했을 때 ‘네이버 로그인’ 패키지 관련 설정으로 인해 이슈가 발생하는 가능성이 있어보입니다.

이전에 제보들어왔던 이슈와 동일 이슈인지 확인 및 AppDelegate.swift 파일 확인 부탁드리겠습니다.

안녕하세요.

해당 이슈는 임시로 카카오톡 설치 여부와 관계 없이 웹으로 로그인하게 해서 처리한 상황인데, 다시 해결은 해야해서 추가 문의드립니다. 앞서 글 남겨주신 saintdin의 직장 동료로, 해당 플러터 앱을 개발하고 있는 담당자입니다.
첨부해주신 이슈와는 상이한 것으로 보이며, AppDelegate 내용 하기에 공유드립니다.
현재 네이버 로그인은 정상적으로 되는 상황이고, AppDelegate 파일 안의 func 2개의 순서를 바꿔도 문제가 해결되지는 않는 상황입니다.

import UIKit
import Flutter
import Foundation
import NaverThirdPartyLogin

// Apple Carplay 에서 앱을 클릭했을 때 빈 화면이 아닌 의도된 에러 화면이 나오기 위한 전역 설정
let flutterEngine = FlutterEngine(name: "SharedEngine", project: nil, allowHeadlessExecution: true)

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        if #available(iOS 10.0, *) {
          UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
        }

    //     GeneratedPluginRegistrant.register(with: self)
    //     return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        // Apple Carplay 를 위한 코드
        flutterEngine.run()
        GeneratedPluginRegistrant.register(with: flutterEngine)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions);
      }

  override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
           if url.absoluteString.hasPrefix("kakao"){
              super.application(app, open:url, options: options)
              return true
           } else if url.absoluteString.contains("thirdPartyLoginResult") {
              NaverThirdPartyLoginConnection.getSharedInstance().application(app, open: url, options: options)
              return true
           } else {
              return true
           }
       }
}

위 내용에 이어서, 현재 저희가 운영하는 앱은 애플 카플레이 적용을 위해 따로 SceneDelegate 파일을 사용하고 있고 이에 따른 Info.plist 설정도 있습니다.
혹시 몰라 관련 내용을 다 걷어냈을 때는 카카오톡으로 로그인이 정상 작동하는 것을 좀전에 확인했습니다.
네이버 로그인 또한 앱을 활용한 로그인인데 카카오톡 로그인은 어떤 차이가 있어서 중간에 문제가 생기는 것인지 알기가 쉽지 않네요.

애플 카플레이 설정을 위해 추가 작업한 내용은 아래와 같습니다.

  1. AppDeletegate 파일에서 flutterEngine 전역 변수로 설정
  • 이는 SceneDelegate 파일에서도 접근할 수 있게 하기 위함으로, 카플레이에서 앱을 눌렀을 때 검은 화면이 아닌 특정 메시지를 표시할 수 있도록 별도 설정한 부분입니다. (멀티 윈도우 지원)
  1. SceneDeletegate 파일 작성
  • 해당 파일 내용은 아래 공유드립니다.
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }

        window = UIWindow(windowScene: windowScene)
        let controller = FlutterViewController.init(engine: flutterEngine, nibName: nil, bundle: nil)
        window?.rootViewController = controller
        window?.makeKeyAndVisible()
    }
}
  1. SceneDelegate 파일 활용을 위해, 아래 내용을 Info.plist에 삽입
<key>UIApplicationSceneManifest</key>
        <dict>
          <key>UIApplicationSupportsMultipleScenes</key>
          <true />
          <key>UISceneConfigurations</key>
          <dict>
            <key>CPTemplateApplicationSceneSessionRoleApplication</key>
            <array>
              <dict>
                <key>UISceneConfigurationName</key>
                <string>CarPlay Configuration</string>
                <key>UISceneDelegateClassName</key>
                <string>flutter_carplay.FlutterCarPlaySceneDelegate</string>
              </dict>
            </array>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
              <dict>
                <key>UISceneConfigurationName</key>
                <string>Default Configuration</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                <key>UISceneStoryboardFile</key>
                <string>Main</string>
              </dict>
            </array>
          </dict>
        </dict>

감사합니다.

좀 더 찾아보니 해당 글 SceneDelegate 에 들어가야하는 카카오 로그인 iOS 전용 설정을 해줘야하는 듯 한데… 플러터에서 해당 iOS 전용 설정을 하는 방법을 혹시 알려주실 수 있으실까요?

SceneDelegate.swift 에서 url을 전달받는 메소드인 scene(_:openURlContexts:) 를 아래와 같은 형태로 구현했을 때도 동작하지 않는지 확인 한번 부탁드립니다

    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let context = URLContexts.first else {
            return
        }
        
        if let flutterAppDelegate = (UIApplication.shared.delegate as? FlutterAppDelegate) {
            let url = context.url
            var options: [UIApplication.OpenURLOptionsKey: Any] = [:]
            options[.sourceApplication] = context.options.sourceApplication
            options[.annotation] = context.options.annotation
            
            flutterAppDelegate.application(UIApplication.shared, open: url, options: options)
        } else {
            print("FlutterAppDelegate is not available")
        }
    }