목차

티스토리 뷰

728x90
반응형

안녕하세요 🐾

카카오톡 로그인에 이어 네이버 로그인 SDK 연동 과정도 정리하려 글을 남깁니다.

네이버 로그인 SDK는 object-c로 되어있어 익숙하지 않아 그런지 카카오톡 로그인보다 좀 더 많이 헤매었던것 같네요 🤣

로그인 연동 작업은 할 때마다 항상 새로운 것 같습니다 껄껄

 

다른 SNS 로그인 SDK 관련 글도 있으니 아래 링크 참고 부탁드립니다 :)

 

2023.12.26 - [iOS/Swift] - [iOS] 구글 로그인 SDK 연동하기

2023.12.22 - [iOS/Swift] - [iOS] 페이스북 로그인 SDK 적용

2023.06.21 - [iOS/Swift] - [iOS] 카카오톡 로그인 SDK 연동하기

 

※ 23년 6월 SDK 기준으로 작성된 글 입니다.

 


 

1. 애플리케이션 설정

먼저 네이버 개발자 페이지에서 로그인을 연동을 진행할 애플리케이션을 생성합니다.

만약 생성이 되어있다면, 이 과정은 생략해주세요!

 

애플리케이션 등록 선택 후 이름을 입력하고 사용할 API네이버 로그인으로 선택합니다.

그러면 아래와 같이 사용자 정보에 대한 권한 목록이 보여지는데 이 중 사용자에게 요청할 정보에 대해 필수, 추가(Optional) 여부를 체크합니다.

 

다음으로 화면 하단에 환경 추가 - iOS를 선택합니다.

다운로드 URLURL Scheme을 입력해야 등록하기 버튼이 활성화 됩니다.

다운로드 URL은 앱을 다운받을 수 있는 앱스토어의 주소를 올리면 되는데, 사진처럼 임시로 적어두고 수정하여도 테스트하는데는 지장이 없습니다 :)

URL Scheme은 프로젝트의 Bundle identifier를 입력해주세요!

 

등록이 완료되면 아래와 같이 생성된 애플리케이션의 정보를 볼 수 있습니다.

이제 프로젝트 설정으로 넘어갑시다.

 

 

2. 설치 및 설정

2.1 설치

podfile에 아래의 pod를 추가 후 터미널에서 pod install을 수행해 주세요.

pod 'naveridlogin-sdk-ios'

설치가 완료되면 .xworkspace를 열어줍니다.

 

 

2.2. 설정

프로젝트 TARGETS - info - URL Types - + 를 선택해 아래와 같이 URL 유형을 하나 생성해 줍니다. 

identifier의 이름은 naverlogin으로 하였고, URL Schemes는 프로젝트의 Bundle identifier를 입력했습니다.

 

그리고 info - Custom iOS Target Properties - Queried URL Schemes에 두 개의 아이템을 추가해 줍니다.

아이템에 들어갈 값은 아래와 같이 naversearchapp, naversearchthirdlogin 입니다.

 

다음으로 iOS 네이버 로그인 SDKobjective-c로 만들어져 있기 때문에 로그인 API 이용에 필요한 상수값을 입력하는 헤더파일에 직접 값을 입력해 주어야 합니다. 저는 처음 연동할 때 이 구간에서 헤맸었습니다. 퓨_퓨

 

먼저 Xcode 하단 파일 검색창에 naverThirdPartyLogin을 입력해볼까요?

.xcframework로 끝나는 뭔가뭔가 하나가 아래와 같이 보일텐데 우클릭 - Show in finder를 선택합니다.

 

그 다음 파인더에서 아래의 경로를 따라 쭉 들어가 주세요.

ios-arm64_armv7 - NaverThirdPartyLogin.framework - Headers - NaverThirdPartyConstantsForApp.h

 

NaverThirdPartyConstantsForApp.h을 열고 스크롤을 아래로 내려보면 #define에 선언되어있는 값을 아래와 같이 이전에 생성했던 개발자 페이지의 애플리케이션 정보를 참고하여 변경해주면 됩니다.

저는 이 중 상단의 kServiceAppUrlScheme은 처음 세팅된 값 그대로 놔두었는데 테스트 하는데는 문제가 없어 그냥 두었지만, 위에서 앱 등록시 입력한 URL Scheme(ex. com.test.asuum)을 입력해 주시면 됩니다 :)

 

이제 마지막으로 AppDelegate.swiftSceneDelegate.swift에서 설정에 필요한 코드를 추가해 볼까요!

먼저 AppDelegate.swift에서 아래의 코드를 추가해 주세요.

import NaverThirdPartyLogin

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   ...
    // naver
    let instance = NaverThirdPartyLoginConnection.getSharedInstance()
    // 네이버 앱으로 인증하는 방식 활성화
    //instance?.isNaverAppOauthEnable = true
    // Safari에서 인증하는 방식 활성화
    instance?.isInAppOauthEnable = true
    // 인증 화면을 iPhone의 세로 모드에서만 사용하기
    instance?.isOnlyPortraitSupportedInIphone()

    // 네이버 아이디로 로그인하기 설정
    // 앱 등록시 입력한 URL Scheme
    instance?.serviceUrlScheme = "com.test.assum"
    // 앱 등록후 발급받은 클라이언트 아이디
    instance?.consumerKey = "YOUR_CLIENT_ID"
    // 앱 등록 후 발급받은 클라이언트 시크릿
    instance?.consumerSecret = "YOUR_CLIENT_SECRET"
    // 앱 이름
    instance?.appName = "네이버테스트"
   ...

}

 

NaverThirdPartyConstantsForApp.h에서 수정했던 값과 마찬가지로 위에서도 동일한 값을 입력해 주시면 됩니다.

다음으로 SceneDelegate.swift에서 아래의 코드를 입력해주세요.

import NaverThirdPartyLogin
...

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
  ...
    // 네이버 로그인 화면이 새로 등장 -> 토큰을 요청하는 코드
    NaverThirdPartyLoginConnection
        .getSharedInstance()
        .receiveAccessToken(URLContexts.first?.url)
  ...
}

iOS 13.0 이후부터 앱 UI와 관련된 생명주기는 SceneDelegate에서 컨트롤하기 때문에 위와 같은 코드가 필요합니다.

이제 모든 설정은 끝났고, API를 요청하고 응답을 받아봅시다! 🎉

 

3. 네이버 로그인 API 호출

먼저, 화면은 아래와 같이 간단하게 구성되어 있습니다.

 

먼저 해당 뷰컨트롤러에서 네이버 로그인 관련 인스턴스를 초기화하고 요청에 의한 대리자 메소드를 받기 위해 아래의 코드를 넣어줍니다.

버튼의 액션을 보시면 requestThirdPartyLogin()은 로그인 요청, requestDeleteToken()은 로그아웃 요청 입니다.

import NaverThirdPartyLogin

// Class member property
let naverLoginInstance = NaverThirdPartyLoginConnection.getSharedInstance()
let disposeBag = DisposeBag()

override func viewDidLoad() {
    ...
    super.viewDidLoad()
    naverLoginInstance?.delegate = self
    bindButtons()
    ...
}

private func bindButtons() {
    ...
    // naverLogin
    naverLoginBtn.rx.tap.asDriver()
        .drive(onNext: { [weak self] _ in
            self?.naverLoginInstance?.requestThirdPartyLogin()
        })
        .disposed(by: disposeBag)
    // naverLogout
    naverLogoutBtn.rx.tap.asDriver()
        .drive(onNext: { [weak self] _ in
            self?.naverLoginInstance?.requestDeleteToken()
        })
        .disposed(by: disposeBag)
    ...
}

 

extension을 이용해 네이버 로그인 대리자 메소드 수행을 담당하는 구역을 아래와 같이 나누어놓았습니다.

하단의 getInfo()Alamofire를 사용하여 네이버 서버와 API 통신을 수행합니다.

import Alamofire

extension ViewController: NaverThirdPartyLoginConnectionDelegate {
    // 로그인에 성공한 경우 호출
    func oauth20ConnectionDidFinishRequestACTokenWithAuthCode() {
        print("Success login")
        self.textField.text = "naver success login"
        getInfo()
    }
    
    // referesh token
    func oauth20ConnectionDidFinishRequestACTokenWithRefreshToken() {
        naverLoginInstance?.accessToken
    }
    
    // 로그아웃
    func oauth20ConnectionDidFinishDeleteToken() {
        print("log out")
        self.textField.text = "naver log out"
    }
    
    // 모든 error
    func oauth20Connection(_ oauthConnection: NaverThirdPartyLoginConnection!, didFailWithError error: Error!) {
        print("error = \(error.localizedDescription)")
        self.textField.text = "naver error : \(error.localizedDescription)"
        self.naverLoginInstance?.requestDeleteToken()
    }
    
    // RESTful API, id가져오기
    func getInfo() {
        guard let isValidAccessToken = naverLoginInstance?.isValidAccessTokenExpireTimeNow() else { return }

        if !isValidAccessToken {
            return
        }

        guard let tokenType = naverLoginInstance?.tokenType else { return }
        guard let accessToken = naverLoginInstance?.accessToken else { return }
        guard let refreshToken = naverLoginInstance?.refreshToken else { return }

        let urlStr = "https://openapi.naver.com/v1/nid/me"
        let url = URL(string: urlStr)!

        let authorization = "\(tokenType) \(accessToken)"

        let req = AF.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: ["Authorization": authorization])

        req.responseJSON { response in
            guard let result = response.value as? [String: Any] else { return }
            guard let object = result["response"] as? [String: Any] else { return }
            guard let name = object["name"] as? String else { return }
            guard let email = object["email"] as? String else { return }
            guard let id = object["id"] as? String else {return}
            
            
            let contentText =
            "user name : \(name)\n userEmail : \(email)\n userGender : \(id)\n tokenType : \(tokenType)\n accessToken : \(accessToken)\n refreshToken : \(refreshToken)"
            
            self.textField.text = contentText
        }
    }
}

 

 

실행 화면은 아래와 같습니다.

로그인 버튼을 누르면 사용자 정보 권한 요구 화면이 뜨고,

 

동의하기를 누른 후 사용자 정보를 가져오는데 성공하면 textField에 아래와 같이 표시됩니다.

 

 

읽어주셔서 감사합니다 :)

틀린 부분이 있다면 알려주세요!

 

4. 참고

반응형
댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함