본문 바로가기
네이버 커넥트재단 부스트캠프/그룹프로젝트

[WeTri][OAuth] 애플로그인 with 백엔드

by Joahnee 2023. 11. 22.

해당 게시글은 네이버부스트캠프에서 그룹 프로젝트를 진행하며 기록하는 내용입니다.

틀린 내용이 있을 수 있습니다. 
저희 프로젝트는 WeTri입니다.

많이 구경하러 와주세요!

https://github.com/boostcampwm2023/iOS08-WeTri

 

🚀 도입부

 

Apple 로그인을 다른 OAuth 로그인에 비해 어렵다는 말만 들었지, 실제로 해본적은 없어서 제가 로그인 기능을 맡게 되었습니다.

 

저희는 최소한의 기능을 구현하기위해 Apple로그인만 구현하기로 했는데요!

 

OAuth를 담당하시는 백엔드 캠퍼분께서 아래와 같은 요청을 주셨습니다!

 

 

🗣️ 요청사항 대응

 

이 모든것을 얻을 수 있는곳은 Apple Developer 사이트의 Certificates, Identifiers & Profiles 페이지 입니다.

 

Identifiers에 들어가서 해당 목록을 확인해 보시면 각종 정보가 들어있는데요!

 

Identifier를 등록안하신 분은 따로 + 버튼이 있으실거라 그 버튼을 눌러서 등록하시면 됩니다.

 

후에 등록된곳에 들어가보면 App ID Prefix와 BundleID가 있는데요

 

App ID Prefix에 Team_ID가 적혀 있습니다.

 

그리고 Bundle ID가 Cilent_ID라고 보시면 될거같습니다.

 

이제 KeyID, Private Key만 드리면 될것같습니다.

 

저희는 부스트캠프를 진행하는 동안에 개인계정이 아니라 회사(?)에 소속된 계정을 사용하는거라서 Private Key, KeyID는 따로 마스터에게 요청드려서 받았습니다. (혹시 궁금하신 분들은 구글링 해보시면 찾아보기 쉽게 설명해주셨을거에요)

 

🔐 OAuth 2.0 도입 이유 

OAuth를 사용하는 이유가 뭘까요?

 

바로 외부서비스 연동때문에 사용하는데요.

 

저희는 애플로그인을 개발하지만, 예를들어서 개발자의 입장에서 네이버 로그인을 쓴다는건 네이버가 가지고 있는 User의 Resource를 사용하기 위해서 쓰는게 되겠습니다.

(OAuth는 클라이언트의 리소스에 접근하기 위해서 만들어 졌으니까요.)

 

OAuth없이 네이버에서 유저 정보를 가져오려면 사용자의 네이버 아이디 비밀번호를 전부 저장해야겠죠?

 

그렇게 된다면, 아마 비밀번호도 바꿀 수 있을겁니다 🤦

 

그래서 OAuth를 사용하는 겁니다. (유저가 허가해준 정보만 접근할 수 있도록)

 

하지만, 저희 프로젝트에서는 Apple Login으로 가져오는 유저의 정보가 없습니다!

 

그럼에도 불구하고, 도입한 이유는 초기 목표가 앱스토어에 앱을 등록하는 것이기에 로그인이 존재한다면 반드시 AppleLogin이 들어가야 됐었는데요.

 

Login에 너무 많은 리소스를 낭비하고 싶지 않아서 AppleLogin 하나로 끝내기 위해, 도입하는걸 결정했습니다.

 

 

📈 로그인 흐름도

저희 앱의 로그인 흐름도는 아래처럼 되겠습니다!

 

Apple에서 받은 IdentityToken과 AuthorizationCode를 서버에 넘겨주고 accessToken과 RefreshToken을 서버로부터 발급받습니다.

 

다른 OAuth 제공업체는 callBack URL을 통해 Server가 OAuth서비스 제공업체로부터 직접 토큰을 받을 수 있는걸로 알고있는데요.

 

애플로그인은 아래와 같은 방식을 가이드라인으로 내놓고 있고 보안상에도 안전하다고 합니다.

 

 

 

 

🖊️ 구현

애플로그인 버튼 구현

/// LoginViewController.swift
private lazy var appleLoginButton: ASAuthorizationAppleIDButton = {
    let button = ASAuthorizationAppleIDButton(type: .signIn, style: .white)
    button.translatesAutoresizingMaskIntoConstraints = false
    return button
}()

 

애플로그인 버튼이 눌렸을 때, 수행할 함수 구현

/// LoginViewController.swift
func appleLogin() {
   let provider = ASAuthorizationAppleIDProvider()
   let request = provider.createRequest()
   request.requestedScopes = []
   
   let authorizationController = ASAuthorizationController(authorizationRequests: [request])
   authorizationController.delegate = self
   authorizationController.presentationContextProvider = self
   authorizationController.performRequests() 
}

 

애플로부터 로그인을 성공했을때, identityToken과 AuthoirzaiotionCode 받는 Delegate 구현

/// LoginViewController.swift
extension LoginViewController: ASAuthorizationControllerDelegate {
  public func authorizationController(
    controller _: ASAuthorizationController,
    didCompleteWithAuthorization authorization: ASAuthorization
  ) {
    guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
          let identityToken = credential.identityToken,
          let authorizationCode = credential.authorizationCode
    else {
      return
    }
    let authoriztionInfo = AuthorizationInfo(identityToken: identityToken, authorizationCode: authorizationCode)
    credentialSubject.send(authoriztionInfo)
  }
}

 

 

참고

- 첫번째

- 두번째

- 세번째

- ClientSecret 

- OAuth

댓글