美文网首页
iOS - Sign in with Apple

iOS - Sign in with Apple

作者: ienos | 来源:发表于2020-08-10 19:59 被阅读0次

    2019.09.12 苹果发布了一条新的审核规则,要求使用了第三方登陆的 App 需要集成 Sign in with Apple.

    [官方文档]

    基本条件

    • Framework — — Authentication Services
    • iOS 13.0 +
    • Xcode 11.3 +

    集成步骤

    1. Xcode, 在 Capaility 中添加 Sign in with Apple
    2. 代码集成

    Swift 代码

    1. Add a Sign in with Apple Button

    func setupProviderLoginView() {
        let authorizationButton = ASAuthorizationAppleIDButton()
        authorizationButton.addTarget(self, action: #selector(handleAuthorizationAppleIDButtonPress), for: .touchUpInside)
        self.loginProviderStackView.addArrangedSubview(authorizationButton)
    }
    

    Apple Button

    2. Requset Authorization with Apple ID

    • 根据 requestedScopes 获取授权范围,.full.email ,获取 用户全名email
    • 系统将会检查用户是否已经在他们的设备上登陆了 Apple ID。如果用户没有登录,App 将推出一个窗口引导用户到设置页面中登陆 Apple ID
    @objc
    func handleAuthorizationAppleIDButtonPress() {
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        let request = appleIDProvider.createRequest()
        request.requestedScopes = [.fullName, .email]
            
        let authorizationController = ASAuthorizationController(authorizationRequests: [request])
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
    }
    
    

    Authorization
    • 用户名:用户可以编辑账户信息,用户可以编辑他们的姓和名字
    • 邮箱:选择其他 email 作为他们的联系信息,和隐藏他们的 email 在 app 中;如果用户选择隐藏 email 地址,Apple 生成一个代理 email 地址去转发用户的私有 email 地址

    • return window 用于模式推出登陆 Apple 的内容
     func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return self.view.window!
    }
    

    3. Handle User Credentials

    用户授权结果,代理方法会检查该 Credential 是 ASAuthorizationAppleIDCredential 还是 ASPasswordCredential

    • Successful Handler
     func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        switch authorization.credential {
        case let appleIDCredential as ASAuthorizationAppleIDCredential:
                
            // Create an account in your system.
            let userIdentifier = appleIDCredential.user
            let fullName = appleIDCredential.fullName
            let email = appleIDCredential.email
                
            // For the purpose of this demo app, store the `userIdentifier` in the keychain.
            self.saveUserInKeychain(userIdentifier)
                
            // For the purpose of this demo app, show the Apple ID credential information in the `ResultViewController`.
            self.showResultViewController(userIdentifier: userIdentifier, fullName: fullName, email: email)
            
        case let passwordCredential as ASPasswordCredential:
            
            // Sign in using an existing iCloud Keychain credential.
            let username = passwordCredential.user
            let password = passwordCredential.password
                
            // For the purpose of this demo app, show the password credential as an alert.
            DispatchQueue.main.async {
                self.showPasswordCredentialAlert(username: username, password: password)
            }
                
        default:
            break
        }
    }
    

    建议在自己的账号系统下面加上 useridentifier

    • Failed Handler
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        // Handle error.
    }
    

    4. Request Existing Credentials

    func performExistingAccountSetupFlows() {
        // Prepare requests for both Apple ID and password providers.
        let requests = [ASAuthorizationAppleIDProvider().createRequest(),
        ASAuthorizationPasswordProvider().createRequest()]
            
        // Create an authorization controller with the given requests.
        let authorizationController = ASAuthorizationController(authorizationRequests: requests)
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
    }
    
    • 如果用户已经请求过 Apple ID (ASAuthorizationAppleIDCredential)和 iCloud keychain password(ASPasswordCredential),这个操作和 Request Authorization with Apple ID 类似,这个方法调用之后会回 authorizationController(controller:didCompleteWithAuthorization:)

    5. Check User Credentials at Launch

    检查 App 是否已 AppleID 登陆授权

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        appleIDProvider.getCredentialState(forUserID: KeychainItem.currentUserIdentifier) { (credentialState, error) in
        switch credentialState {
            case .authorized:
                break // The Apple ID credential is valid.
            case .revoked, .notFound:
                // The Apple ID credential is either revoked or was not found, so show the sign-in UI.
                DispatchQueue.main.async {
                    self.window?.rootViewController?.showLoginViewController()
                }
            default:
                break
            }
        }
        return true
    }
    

    6. ASAuthorizationError Code

    • Cancel — — 1001
    • Unknown — — 1000
    • Failed — — 1004
    • NotHandled — — 1003
    • InvalidResponse — — 1002

    注意事项

    • 基于目前的调查,Sign in with Apple 能够获取授权信息有: email、fullName(包括 First Name 和 Last Name)。在第一次授权登陆 App 中(之后 Apple ID 会保存该 App 已授权),必须确保用户被正确创建(如果云端创建失败,需要保存在本地);因为除了第一次外,之后再次登陆除了返回 userIdentifier 之外,不会返回用户的任何信息。
      在测试阶段,我们可以手动删除 Apple ID 和 App 的授权绑定(iPhone Setting -> Apple ID -> Password & Security -> Apple ID logins -> {YOUR APP} -> Stop using Apple ID)

    相关文章

      网友评论

          本文标题:iOS - Sign in with Apple

          本文链接:https://www.haomeiwen.com/subject/oqtsdktx.html