哈Ha!
今年夏天,在WWDC 2019大会上,苹果推出了自己
的使用Apple登录系统,并
强制要求 App Store中所有使用社交媒体登录的应用程序都必须使用该系统。 使用自己的授权的教育,公司,政府和商业应用程序除外。 对于使用Apple登录,Apple提供了高质量的
文档 ,在本文中,我们将使用CIAN的示例来描述如何在我们的服务中实现它。

配置苹果开发者帐户
集成工作始于设置开发者帐户。 首先,您需要为您的App ID启用“使用Apple登录”选项。 为此,请转到
Apple开发者帐户中的标识符列表 ,选择必要的App ID并为其启用“使用Apple登录”选项。
现在,我们配置服务ID-Web应用程序的唯一标识符,您将需要使用Apple API访问登录。 每个应用程序ID总共最多可以创建5个服务ID。 为此,请单击用于创建标识符的按钮,选择“服务ID”,填写必填字段,然后在“使用Apple登录”字段中单击“编辑”。 将打开一个表单,供我们选择正确的主应用程序ID,指定网络域,并在成功登录后列出用于重定向的URL。 请记住,您只能输入10个返回URL:

要保存,请单击保存,继续并注册。 是的,对于任何配置更改,必须单击所有三个按钮,否则更改将不会生效。
现在,在“服务ID”列表中,选择创建的标识符,然后在“使用Apple登录”字段中再次单击“编辑”。 在打开的窗口中,网址字段旁边,我们看到两个新按钮:

苹果需要此文件来验证您的资源。 下载它并将其放在您的资源上。 立刻,这种假装对我们不起作用:当我们的管理员添加文件时,对位于其他位置的文件的重定向(302)在指定的url上起作用,Apple并未对其进行验证。 然后,我必须放置文件以通过URL直接访问(200)。 Apple成功检查文件后,该域旁边的绿色复选标记会亮起:

从标识符部分,转到“密钥”部分并创建一个新密钥。 为此,请选中“使用Apple登录”复选框,然后首先单击“配置”以检查App ID,然后单击“继续”:

在下一个屏幕上,请确保使用密钥下载文件并将其保存在安全的地方,因为离开此屏幕后,将无法下载密钥。 在同一页面上,您可以看到我们仍然需要的密钥ID:

使用Apple登录对用户有一个好处:它允许您提供伪造的电子邮件,您只能从受信任的地址向其发送邮件。 在这种情况下,需要其他配置。 打开“更多”部分,在“使用Apple登录”部分中单击“配置”,然后输入您的URL:

将“使用Apple登录”按钮添加到iOS应用。
CIAN在三个平台上工作:iOS,Android,Web。 有一个适用于iOS的本地SDK,因此授权如下所示:

要将“使用Apple登录”添加到iOS应用程序,请添加ASAuthorizationAppleIDButton按钮并在其上悬挂点击处理程序:
let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests()
除了ASAuthorizationAppleIDProvider之外,还要注意ASAuthorizationPasswordProvider,它使您可以从钥匙串中获得一堆“登录密码”。
现在,我们实现ASAuthorizationControllerPresentationContextProviding:
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { return self.view.window! }
创建一个报告成功或错误的ASAuthorizationControllerDelegate委托:
public func authorizationController( controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization ) { guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential, let code = appleIDCredential.authorizationCode, let codeStr = String(data: code, encoding: .utf8) else {
我们将接收到的authorizationCode发送到服务器,并等待后端关于系统中授权成功的响应。
我们为网络和Android实施与Apple的登录
突然,对于Android和Web,Apple不提供SDK,因此在两种情况下,您都需要打开Apple授权页面,并且过程将有所不同:

登录页面的URL如下:
https:
考虑其参数:
- client_id-上面注册的服务ID。
- redirect_uri-通过AppleID成功进行身份验证后,将用户重定向到的URI。 设置Apple Developer时,我们在上面指定了此URI。
- state-Apple在调用redirect_uri时将返回的用户的会话标识符,以便我们可以检查发件人。 您可以发明自己生成此参数的规则,例如,随机字符串。
- 作用域-此参数指示需要用户提供哪些信息。 例如,如上例所示,名称,电子邮件或两者兼而有之。
- response_type-此参数指示需要哪种形式的响应。 它可以是代码或id_token。 如果选择id_token,则需要使用response_mode参数指定它,您可以在其中指定查询,片段和form_post。
通过appleID成功进行两因素身份验证后,Apple将调用指定的redirect_uri并传递状态和代码参数:
curl -X POST \ 'https:
在code参数中,传递了一次用户验证码,该验证码有效期为5分钟。 在状态参数中,创建授权表单时发送的会话标识符,在用户参数中,用户数据。
资料检索
在所有客户端上,要保存用户数据,您需要从Apple获得access_token。 为此,请首先请求authorization_code:
curl -X POST https:
在此请求中:
- client_id表示为Web应用程序创建的ServiceID和iOS应用程序的AppID。
- 代码-重定向或从iOS客户端转移后,我们收到的价格更高
- 在grant_type参数中,我们达到了获得令牌的目的:授权(authorization_code)或令牌的续签(refresh_token)
- 在client_secret参数中-基于在应用程序注册期间获得的密钥的JSON Web令牌。
您可以在Python中创建JSON Web令牌:
claims = { 'iss': APPLEID_TEAM_ID, 'aud': 'https://appleid.apple.com', 'sub': client_id, 'iat': current_timestamp, 'exp': current_timestamp + expire_period, } headers = {'kid': 'APPLEID_KEY_ID', 'alg': 'ES256'} client_secret = jwt.encode(payload=claims, key=secret_key, algorithm='ES256', headers=headers).decode('utf-8')
如果一切顺利,则响应中将包含以下参数:
{ "access_token":"ufhzch", "token_type":"Bearer", "expires_in":3600, "refresh_token":"some_refresh_token", "id_token":"some_long_signed_jwt_token" }
万岁,这是access_token。 随之而来的是refresh_token,可以在必要时对其进行更新。
用户信息存储在id_token字段中,但需要对其进行解码:
public_key = jwt.algorithms.RSAAlgorithm.from_jwk( json.dumps(apple_public_key) ) data = jwt.decode( id_token, public_key, algorithm="RS256", verify=True, audience=client_id, )
Apple_public_key是可以从
链接获取的公共密钥
。解码后,我们得到:
data = { "iss": "https://appleid.apple.com", "aud": client_id, "exp": 1570379521, "iat": 1570378921, "sub": " ", "at_hash": "8ZDF6j786IQf9mA", "email": "someemail@gmail.com", "email_verified": "true", "auth_time": 1570378804 }
当用户首次通过“使用Apple登录”登录到您的服务时,电子邮件仅传输一次。 下次,只有在用户自行取消绑定应用程序时,Apple才会传输此数据。 苹果公司的这项授权不同于其他可通过API获得数据的服务,我们未找到他们计划实施类似服务的信息。
在此答案中,我们需要每次都传输的参数子和电子邮件,因此我们将它们保存在系统中并通知客户成功的授权。 利润。
初步结果
在发布具有Apple登录功能的CIAN新版本之后,在第一天的第一天,它就占了iOS 13新注册的三分之一,现在,它在所有iOS版本中都排名第二,仅次于VK。 该站点上使用AppleID的注册很少,但注册数量正在缓慢增长。 现在,我们计划通过Android应用程序上的AppleID启用授权,并查看有多少用户将以这种棘手的方式进行注册。