Flutter/SNS Login

[Flutter] Apple Login 심화 구현 - Ios App

주톨 2024. 9. 30. 03:39
728x90

 

 

https://jutole.tistory.com/156

 

[Flutter] Apple Login 구현 - Ios App

설정이 안 된 분은 아래글을 통해 설정을 하고 와주세요. https://jutole.tistory.com/154 [Flutter] Apple Login 설정 - Ios AppIos App 환경에서 apple 로그인을 하기 위한 설정 입니다.   1.  App IDs 등록   이러

jutole.tistory.com

 

이전에 Apple Login 간단하게 구현해 보았습니다. 이번 글에서는 조금 더 심화 구현을 해보겠습니다.

 

 

1.  Nonce

Nonce는 Apple 로그인 (Sign in with Apple) 과정에서 사용하는 중요한 보안 요소입니다. Apple 로그인의 Nonce는 암호화된 임의 문자열로, 요청을 보낼 때 이를 사용하여 인증 과정의 보안을 강화합니다. 주로 *replay attack(재전송 공격)*을 방지하는 용도로 사용됩니다.

 

return SignInWithAppleButton(
  onPressed: () async {
    final result = await SignInWithApple.getAppleIDCredential(
      scopes: [
        AppleIDAuthorizationScopes.email,
        AppleIDAuthorizationScopes.fullName,
      ],
      nonce: _getNonce(),
    );
  },
);

String _getNonce() {
  const charset =
      '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';

  final random = List<int>.generate(
    32,
    (_) => charset.codeUnitAt(
      (Random().nextDouble() * charset.length).floor(),
    ),
  );

  final bytes = utf8.encode(
    String.fromCharCodes(random),
  );

  /// import 'package:crypto/crypto.dart'; 패키지 추가 사용
  final sha256Nonce = sha256.convert(bytes).toString();

  return sha256Nonce;
}

 

이전 구현에서 했던 기본적인 AppleLogin 방법에서 nonce를 추가할 수 있습니다. 클라이언트가 임의로 생성한 무작위 값을 Apple로그인과 함께 보내고 Apple에서는 해당 값을 identityToken에 같이 실어서 보내줍니다.

 

 

 

2. IdentityToken

Apple에서 발급하는 JWT 형식의 신원 확인 토큰.

 

result.identityToken

 

 

AppleLogin을 하고 받은 응답값에는 identityToken이 있습니다. 해당 토큰은 Apple에서 발급한 JWT 형식의 토큰이기 때문에 디코딩을 하면 해당 유저의 신원을 확인할 수 있습니다.

 

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

(디코딩 사이트)

 

 

{
  /// 토큰 발급한 주체
  "iss": "https://appleid.apple.com",
  
  /// 토큰의 수신자
  "aud": "jutole.app.customer",
  
  /// 토큰 만료 시간
  "exp": 1727718782,
  
  /// 토큰 발급 시간
  "iat": 1727632382,
  
  /// userIdentifier 유저 고유 식별자
  "sub": "001381.71cebe533162466fd6229190b49d4329.0111",
  
  /// 보안 용도로 사용되는 고유한 문자열
  "nonce": "d6ead4b4e3cb70c1deeec1d2429a4ac5a0b4b819dab04b45f0cf5d403e52525a",
  
  /// 인증 코드가 안전하게 전송되었음을 검증하는 데 사용
  "c_hash": "PQiQDbxZCaTz1kuiHkjG5B",
  
  /// 사용자의 이메일 주소
  /// 용자의 실제 이메일을 보호하기 위해 Apple이 제공하는 사설 이메일 주소
  "email": "ABCDEFG@privaterelay.appleid.com",
  
  /// 사용자의 이메일 주소가 검증되었는지를 나타내는 불리언 값
  "email_verified": true,
  
  /// 사용자가 개인 이메일 보호 기능을 사용하고 있는지 여부
  "is_private_email": true,
  
  /// 사용자가 마지막으로 인증된 시간
  "auth_time": 1727632382,
  
  /// Nonce 지원 여부
  "nonce_supported": true,
  
  /// 사용자가 실제 사용자임을 나타내는 상태 코드
  /// 0 : 사용자에 대한 정보가 불확실하거나 제공되지 않음.
  /// 1 : 실제 사용자가 아니거나 테스트 계정
  /// 2 : 실제 사용자
  "real_user_status": 2
}

 

identityToken을 디코딩하면 위와 같은 데이터를 알 수 있습니다. 1번에서 보낸 nonce가 응답값으로 오는 게 확인이 됩니다. 이것으로 클라이언트에서 보낼 때의 nonce와 응답으로 온 nonce값을 비교해서 중간에 위변조가 되었는지 여부를 알 수 있습니다.

 

identityToken에 userIdentifier도 포함하고 있어 해당 토큰만 서버에 전달하면 서버에서 해당 토큰을 디코딩해서 처리할 수 있습니다.

(identityToken에 사용자 이름은 포함되어 있지 않기 때문에 따로 보내야 합니다.)

 

 

 

 

3.  Email Source 추가

일반적으로 사용자의 이메일로 메일을 보내거나 하는 이벤트는 정상적으로 이루어집니다. 하지만 AppleLogin에서 사용자가 *이메일 가리기* 기능을 선택해 비공개 이메일로 설정되어 비공개 이메일로 메일을 보내면 정상적으로 메일이 가지 않습니다.

 

일반 이메일 : jutoleofficial@gmail.com

비공개 이메일 : ABCDEFG@privaterelay.appleid.com

 

 

 

https://developer.apple.com/account/resources/services/list

 

로그인 - Apple

 

idmsa.apple.com

 

이런 상황에서 해결 방법은 위에 사이트를 들어가서 *Sign in With Apple for Email Communication* -> *Configure* -> *Email Sources* 추가 버튼을 눌러줍니다.

 

 

 

그러면 위와 같은 창이 뜨는데 *Domains and Subdomains*에 메일을 보낼 domain을 입력하고 저장하면 됩니다.

 

* gmail.com 같은 도메인은 추가도 안되고 발송도 안 되는 것 같습니다. 

* 되시는 분 있으면 알려주세요. 

* 회사 도메인 추가하면 회사 도메인으로 메일 발송시 정상적으로 발송됩니다.