카테고리 없음

Django에 애플 로그인 연동하기 (feat. Flutter)

천만일 2025. 2. 1. 16:21

배경

이전에 Django에 구글 로그인 연동하기 (feat. Flutter)라는 글을 공유드렸습니다.
이번에는 후속으로 애플 로그인을 연동하는 법에 대해 남겨보려고 합니다.


앱 스토어에 앱을 올리고 싶다면 구글 로그인만 연동해서는 올릴 수 없습니다.
심사 과정에서 구글 로그인만 발견된다면 반려 사유가 될 수 있습니다.


따라서 모바일 앱을 운영하시는 분들이라면 구글과 애플 로그인 중 하나만 구현하는 일은 없으실 것이라고 생각합니다.
저번과 동일하게 환경은 다음과 같습니다.

  • Server: Django
  • Client: Flutter

이런 분들께 추천!

  • 애플 로그인을 구현해야 하는데 애플 생태계에 친숙하지 않은 분들
  • Flutter로 애플 로그인을 구현하는 법을 빠르게 알고 싶은 분들

Apple 개발자 계정


먼저 애플 개발자 계정이 필요합니다.
애플은 개발자 계정을 만들고 유지하는데 비용이 발생하는 점을 유의해주세요.


식별자 생성

Apple 개발자 계정 페이지에서 식별자를 생성해주세요.


  1. App IDs 선택


  2. App 타입 선택


  3. 앱 번들 ID와 설명 작성


  4. 아래로 내린 후, Capabilities에서 Sign In with Apple 설정



    Edit 버튼을 통해 다음과 같이 설정


    상단부: 애플 로그인 계정을 다른 앱과 공유할 것인지
    하단부: 사용자 혹은 계정에 중요한 업데이트가 있을 때, 안내하기 위한 서버 엔드포인트


  1. Register 버튼을 통해 식별자 생성 완료

Key 생성

위에서 생성한 식별자에서 사용할 수 있는 키를 발급합니다.

  1. Key의 이름과 설명 작성

  2. Sign in wigh Apple 기능 활성화


  1. configure에서 Key에 대응되는 App ID를 설정

    위에서 생성한 생성자를 선택합니다.

  2. Register 버튼을 통해 등록

  3. Key를 등록하면, 최초에 한하여 받을 수 있는 비밀 키(*.p8)를 다운로드 받습니다.


위 과정들을 통해 애플 로그인을 위한 계정 설정 및 키 발급 과정이 완료되었습니다.


이번 작업을 통해 애플 로그인 또한 전반적인 oAuth의 작동 방식과 다르지 않다는 점을 알게 되었는데요, 구현 방법을 하나씩 알아보겠습니다.



클라이언트 구현

Flutter에서는 sign_in_with_apple이라는 패키지가 가장 많이 사용됩니다.


마지막 업데이트가 24년 12월이기 때문에 잘 관리되고 있는 패키지라고 볼 수 있습니다.


해당 패키지의 문서를 통해 Android와 iOS에서 애플 로그인을 설정할 수 있는 방법을 안내하고 있습니다.


iOS (XCode)

  1. Runner - Signing&Capabilities
  2. Bundle Identifier에 식별자 입력
  3. Capability에 Sign in with Apple 추가

Dart (Flutter)

Future<void> _handleSignInWithAppleIntent() async {
    // Request credential for the currently signed in Apple account.
    final AuthorizationCredentialAppleID appleCredential =
        await SignInWithApple.getAppleIDCredential(
      scopes: <AppleIDAuthorizationScopes>[
        AppleIDAuthorizationScopes.email,
        AppleIDAuthorizationScopes.fullName,
      ],
    );

    final String authorizationCode = appleCredential.authorizationCode**;

    //** authorizationCode를 서버로 전송
}

패키지를 사용하는 Dart side는 정말 간단합니다.

획득하고자 하는 사용자 정보의 범위를 설정해서 인증 정보를 받아옵니다.


이 정보를 우리는 서버로 보낼 예정입니다.


서버 구현

서버 구현에는 총 4가지의 key가 필요합니다.

  • 앱의 식별자
  • 개발자 계정 ID
  • Sign in with apple 키 ID
  • Sign in with apple 키 비밀키

  1. 클라이언트로부터 전달받은 authorization_code(인가코드)로 apple id_token 가져오기


    apple에서 제공하는 API (/auth/token)를 통해 인가코드를 id_token으로 변환할 수 있습니다.


    /auth/token API는 request body에 다음 4가지 필드를 반드시 필요로 합니다.

    • client_id ⇒ 앱의 식별자

    • grant_type ⇒ “authorization_code"

    • authorization_code ⇒ 인가 코드

    • client_secret ⇒ JWT


      client_secret이 다른 소셜 로그인과는 다른 점이 있어 꽤나 복병이었습니다.

      공식 문서에 따르면 요구 조건에 따라 직접 JWT를 만들어야 합니다.


      # JWT Header
      {
        "alg": "ES256",
        "kid": "{Sign in with apple 키 ID}"
      }
      # JWT Payload
      {
        "iss": "{Apple 개발자 팀 ID}"
      "iat": "{현재 시간(epoch time)}"
      "exp": "{JWT 만료 시간(epoch time)}"
      "aud": "https://appleid.apple.com",
      "sub": "{앱의 식별자}"
      }

      위 두 데이터를 위에서 발급받은 비밀키(*.p8)로 암호화합니다.


  2. apple id_token을 복호화


    1번에서 발급받은 id_token 또한 JWT입니다.


    바로 payload를 해석해서 사용해도 되지만, JWT의 무결성을 검증하는 작업을 수행해보겠습니다.


    id_token의 header에는 kid라는 필드가 존재합니다.

    kid는 Apple이 id_token을 암호화할 때 사용한 공개키를 의미합니다.


    다음 API에 요청하면 key-value 형태로 다수의 공개키를 확인할 수 있습니다.
    https://appleid.apple.com/auth/oauth2/v2/keys

    [참고] Apple developer 공식 문서


    공개키 목록 중 kid에 해당되는 공개키를 가져옵니다.

    공개키를 활용하여 RS256 알고리즘으로 암호화된 id_token을 복호화합니다.


    다음은 python으로 구현된 복호화 코드입니다.

     import jwt
     from jwt.algorithms import RSAAlgorithm
    
     apple_id_token = "" # JWT 형태의 id_token
     apple_public_key = "" # kid로 찾은 공개키
     APPLE_CLIENT_KEY = "" # 앱의 식별자
    
     decoded_apple_id_token = jwt.decode(
         jwt=apple_id_token,
         algorithms="RS256",
         key=RSAAlgorithm.from_jwk(
             jwk=apple_public_key,
         ),
         audience=APPLE_CLIENT_KEY,
     )

    성공적으로 복호화되었다면, 클라이언트에서 설정한 scope에 해당하는 데이터들을 얻을 수 있습니다.


    이 데이터(ex. email, name)를 통해 서비스를 사용할 수 있는 인가 정보를 생성 후 클라이언트로 전달하면 되겠습니다.


정리

Apple 로그인을 구현하기 위해서는 다른 플랫폼과 다르게 JWT에 대한 이해도가 필요합니다.


인가코드를 검증하고 사용자 정보를 조회하는 과정에서 Apple에서 제공하는 API를 잘 이해하고 적절하게 활용한다면 다른 소셜 로그인과 비슷합니다.


항상 Apple과 관련된 기능은 더 복잡할 것 같다는 막연한 두려움이 있었는데, 잘 정리된 API 문서를 통해 해결할 수 있었습니다.