ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS 소셜로그인 구현 - 구글 로그인 연동
    iOS 2022. 5. 16. 20:16

    안녕하세요 ! 도안입니당 :>

     

    티스토리가 다 쓴 글을 날려버렸어요... 분명 자동저장 열심히했는데 이자식.....

    어쩌겠나요 다시써야지 ᵕ᷄≀ ̠˘᷅

     

     

    >>카카오 로그인 하는 법 보러가기<<

    암튼 지난번 카카오 로그인에 이어서!!

    이번엔 구글 로그인 연동을 해보겠습니다~! (신난다~~)

     

     

    그럼 목차 훑어주고 가실게요~~

     

    iOS 구글 로그인 연동

      결국 자동목차 기능 넣음,, 편하네요><

       

      1. Pod File 설치

      pod 'GoogleSignIn'

      pod file 에 추가해주기 ~ pod install ~~

       

      2. 구글 클라우드 Client ID 받기

      프로젝트 생성

      먼저 구글 클라우드 플랫폼에 프로젝트를 생성하고, iOS용 클라이언트 ID를 만들어야 합니다 ^_^

      왼쪽 상단에 프로젝트 선택하는 박스에서 [새 프로젝트 생성]을 눌러 프로젝트를 만들어봅시다!

      프로젝트를 만드셨으면 왼쪽 탭의 [API 및 서비스] >>[OAuth동의 화면] >> [User Type 외부] >> 앱 이름, 이메일,개발자 연락처 등록하고 저장! 

      Client ID 발급 받기

      [API및 서비스] >> [사용자 인증 정보] >> [+ 사용자 인증 정보 만들기]  >> [OAuth 클라이언트 ID] >> [iOS] >> 번들ID, 앱스토어 ID(있는경우만) 입력

      까지 하시면 클라이언트 아이디가 생성됩니다! >.<

      깃에 클라이언트 ID 를 숨기기 위해서 저는 따로 파일을 분리해서 Struct를 만들어두고 gitignore에 포함시켰어요!

       

      3. 프로젝트 설정

      URL Scheme 추가

      자 저기 URL Types 에 !

      아까 받았던 클라이언트 ID 를 역순 으로 등록해줍니다~~

      클라이언트어쩌고.apps.googleusercontent.com  (x)

      com.googleusercontent.apps.클라이언트어쩌고 (o)

       

      SceneDelegate / AppDelegate 

      이제 프로젝트에 의존성을 주입하고 ! 프로젝트 세팅을 해봅시당

       

      다들 아시다시피, iOS13이후로는 프로젝트 생성시에 SceneDelegate 를 기본으로 채택하게 됩니다.

      근데 제가 못찾은건지 구글공식문서에는 AppDelegate에서 설정하는 법밖에 없더라고요!ㅜ.ㅜ

      일단 구글문서에 나온 방법 ▼

      import GoogleSignIn
      ...
      func application(
        _ app: UIApplication,
        open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]
      ) -> Bool {
        var handled: Bool
      
        handled = GIDSignIn.sharedInstance.handle(url)
        if handled {
          return true
        }
      
        // Handle other custom URL types.
      
        // If not handled by this app, return false.
        return false
      }

      SceneDelegate에서 관리하는 방법 ▼

      import GoogleSignIn
      ...
      func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
              if let url = URLContexts.first?.url {
                  
                  if ((url.scheme?.contains("com.googleusercontent.apps")) != nil) {  //구글 링크인지
                      GIDSignIn.sharedInstance.handle(url)
                  }
              }
          }

      만약 다른 url 도 같이 있다면? 요렇게 구분해줘야겠죠 ?!  ▼

      func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
              if let url = URLContexts.first?.url {
                  
                  if (AuthApi.isKakaoTalkLoginUrl(url)) { //카카오 링크인지
                      _ = AuthController.handleOpenUrl(url: url)
                  }else if ((url.scheme?.contains("com.googleusercontent.apps")) != nil) {  //구글 링크인지
                      GIDSignIn.sharedInstance.handle(url)
                  }
              }
          }

       

      4. 로그인 구현

      GIDConfiguration 생성

      로그인 기능을 할 VC에다가 또 GoogleSignIn 을 임포트 해주고, configuration 생성을 해줍니다.

       

      let signInConfig = GIDConfiguration.init(clientID: "YOUR_IOS_CLIENT_ID")

      로그인

      생성한 configuration으로 로그인을 해봅시다-!

      @IBAction func signIn(sender: Any) {
      	//전 여기서 생성했어요!
      	let signInConfig = GIDConfiguration.init(clientID: "YOUR_IOS_CLIENT_ID")
          
      	GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
          	guard error == nil else { return }
      
          // If sign in succeeded, display the app's main content View.
        }
      }

       

      유저 정보 받아오기

      여기서 받아온 user로 유저 정보를 받아올 수 있어요!!

      Like this

      let email = user.profile?.email 
      let fullName = user.profile?.name	// name = givenName + familyName
      let given = user.profile?.givenName
      let family = user.profile?.familyName
      let profilePicUrl = user.profile?.imageURL(withDimension: 320)

      토큰은 어디갔냐구요? 요렇게 받아오시면 됩니다 :3

      GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
          guard error == nil else { return }
          guard let user = user else { return }
      
          user.authentication.do { authentication, error in
              guard error == nil else { return }
              guard let authentication = authentication else { return }
      
              let idToken = authentication.idToken
              // Send ID token to backend (example below).
          }
      }

      로그아웃

      @IBAction func signOut(sender: Any) {
        GIDSignIn.sharedInstance.signOut()
      }

      까지 하면~!! 필수적인 기능은 끝입니다 🎉🎉

       

       

      5. 추가적인 이슈

      사실 구현을 다 해놓고 로그인 에러가 뜨는 현상이 발생했었습니다 :(

      토큰을 서버에 보냈는데 verify가 안된다는 응답만 오더라고요 이게 무슨일이냐!!! 암만 코드를 뜯어봐도 잘못된게없는데?! 해서 서버 파트랑 얘기를 해봤는데요

      알고보니까 서버측에도 제가 가지고 있었던 ClientID를 알려줘야 했더라고요.

      변경된 클라이언트ID를 서버측에 알려주지 않아서 생긴 문제였습니다!

      클라에서 토큰만 받아서 카카오측에 유효한 토큰인지 확인하는 카카오 로그인과 달리,

      구글이랑 애플은 추가적인 정보(클라이언트 아이디,key id, team id 등등...)를 한번 더 검증하더라고요~

      서버쪽에 클라이언트 아이디 잘 알려주니까 깨끗하게 해결 됐습니다 ^ㅡ^ 

       

       

       

      구글 공식 문서를 참고해서 작성했습니다 XD

      혹시 틀린 부분이나 뭔가 개선할 부분은 댓글로 말씀해주시면 정말 감사하겠습니다!!!(제발료 저도 알고싶어요)

      댓글

    Maybe a whole cake ? 🎂 HAHA!