接入Apple登录

1.概述

本文是对AppleID登录接入的相关总结,希望对其他人能有帮助。

苹果在其WWDC19大会上提出了"Sign In with Apple"的概念,类似于微信一键登录,但也有些区别:

  • 微信存在一个UnionID、OpenID的概念,苹果只有一个AppleID,在同一个开发者账号下的所有应用,这个AppleID是一致的
  • 微信直接通过API就能拿到用户信息,苹果的Oauth2 Code验证接口不返回用户信息,需要客户端上报给服务端
  • 苹果提供的OAuth2 Code的验证接口返回的是一个JWT Token,用户ID隐藏在JWT Token中,需要二次解析
  • 苹果一共提供了两个接口,同时支持了OAuth2和JWT两种认证方案,考虑到通用性,我们这次选择了OAuth2方案

2.申请资源

在发起请求前,需要准备三个参数和一个证书(向IOS客户端负责人申请):

  • Team ID,10个字节的字符串,可以在苹果账户后台中看到,位于右上角
  • Key ID,10个字节的字符串,可以在苹果账户后台配置,参考链接:创建Private Key
  • Client ID,就是 App 的 bundle id
  • Private Key,一个.p8文件,只能从苹果官网下载一次,创建Private Key 文档中有说明

参数示例:

apple\_login\_team\_id = "89XXXX8FZF"

apple\_login\_key\_id = "QPFXXXXW67"

apple\_login\_client\_id = "com.gdinke.soulmatch"

证书示例:

-----BEGIN PRIVATE KEY-----

MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgfYVD9vw6h2aa+69n

JkrymACzR04hck6lOsXXXXXXyBagCgYIKoZIzjXXXXXXRANCAARQdXt9y2lmGY2P

v+5pzghXhKDcIVBizOfEj1IVT7BUXXXXXXXXXXXXXXXXX/WCxDGCOO4dfVU1l3hL

g1Ah7rzS
-----END PRIVATE KEY-----

3.认证流程和时序图

认证流程:

  1. 客户端调用IOS系统API,启动认证流程,需要向Apple发起请求
  2. Apple返回用户的Oauth2 认证code以及用户的信息,例如昵称nickname和邮箱email
  3. 客户端将auth code发送给服务端,接口 https://service.hnyapu.cn/user/account/apple_login
  4. 服务端解析客户端请求中的auth code,向Apple请求认证客户端auth code的有效性,接口:https://appleid.apple.com/auth/token
  5. Apple验证code是否有效
  6. Apple返回用户的AppleID
  7. 服务端返回用户的UID和Session ID

时序图(由Typora+markdown+mermaid生成):

sequenceDiagram

APP客户端 ->> Apple : 1.请求auth code

Apple ->> APP客户端 : 2.返回auth code

APP客户端 ->> + APP服务端 : 3发送auth code

APP服务端 ->> Apple : 4.请求验证auth code

Apple -->> Apple : 5.验证auth code

Apple -->> APP服务端 : 6.返回用户AppleID

APP服务端 -->> - APP客户端 : 7.返回uid和sid给客户端

4.文档和代码

项目代码权限请联系 方楚伟 林旭平 阳雄俊开通

5.参考资料

6.Apple ID服务器加速代理

在测试阶段,我们观察到从大陆机房访问Apple的服务会出现偶尔高延迟,我们怀疑是GFW干扰导致,SRE已经帮忙优化了,提供了4层代理服务器(腾讯北京 ->(腾讯云联网)-> 腾讯香港 -> 公网 -> 苹果服务器),

代理服务器加速效果的测试报告我们整理到了WIKI中: 声圈 Apple服务器连接代理测试

修改/etc/hosts添加如下一行即可生效(使用前需要在测试环境先验证,并确认代理服务器网络层面可达):

10.213.0.4 appleid.apple.com

7.苹果后台操作步骤

在 iOS13 中,如果 App 提供第三方登录,就必须添加 苹果登录 Sign in with Apple 选项,并要求所有开发者于 2020年4月之前 完成现有应用的更新,否则审核不给通过。

iOS 苹果授权登录(Sign in with Apple)系列之Apple Developer配置篇

iOS 苹果授权登录(Sign in with Apple)系列之原生篇

iOS 苹果授权登录(Sign in with Apple)系列之uniapp篇

iOS 苹果授权登录(Sign in with Apple)系列之服务端篇

iOS 苹果授权登录(Sign in with Apple)系列之Apple Developer配置篇 主要写给非 iOS 开发人员(例如 uniapp 开发者)。

登录 Apple Developer

1、打开并登录 苹果开发者网站

https://developer.apple.com

2、点击 Certificates, Identifiers & Profiles 按钮

配置 Sign in with Apple

现有 app 开启 Sign in with Apple

1、选择左边 Identifier 栏目,在右侧选择要开通 苹果授权登录(Sign in with Apple)的 Identifiers 点击打开。

[
](http://www.wangquanwei.com/wp...

2、下拉找到 Sign In with Apple 打钩

右边的 Edit 打开会提示

  1. If you're enabling an App ID for the first time or for a new app, enable the App ID as a primary. You can use primary App IDs on their own or to enable identifiers for related apps and websites through grouping. To enable an App ID for a related app, (for example, an App ID for the iOS version of your Mac app), group it with the existing primary. This will also ensure that users only need to provide consent to share their information with you once for each group of apps and websites.
  2. 如果首次启用应用程序ID或为新应用程序启用应用程序ID,请将该应用程序ID作为主应用程序。你可以自己使用主应用id,或者通过分组来启用相关应用和网站的标识符。要启用相关应用程序的应用程序ID(例如,Mac应用程序的iOS版本的应用程序ID),请将其与现有的主应用程序分组。这也将确保用户只需提供同意,就每组应用程序和网站与您共享一次信息。

然后点击 右上角 save 保存会出现 Modify App Capabilities 弹窗 点击 Confirm

  1. Modify App Capabilities
  2. Adding or removing any capabilities will invalidate any provisioning profiles that include this App ID and they must be regenerated for future use.
  3. 修改应用程序功能
  4. 添加或删除任何功能都将使包含此应用程序ID的任何设置配置文件无效,并且必须重新生成这些配置文件以供将来使用。

注:开启后 profile 将失效需要重新编辑 profile 文件

创建新 app 并开启 Sign in with Apple

1、创建 Identifiers

2、选择 App IDs 并点击右上角 Continue

3、在 Register an App ID 里按下图顺序操作

4、下拉在 Capabilities 里勾选 Sign In with Apple

5、点击右上角 Continue 后按钮会显示为 Register 点击即可

Profiles

现有 app 开启 Sign in with Apple

现有应用在开启 Sign in with Apple 后在 Profiles 里 EXPIRATION 一栏会显示 Invalid

点击这一栏- Generate a Provisioning Profile 页面- Edit -点击 save

下载新的 Profile 即可

创建新 app 并开启 Sign in with Apple

1、在 Profiles 栏右侧点击加号

2、Register a New Provisioning Profile 根据实际情况选择,这里作为演示选择 iOS App Development,选完点击 Continue

3、选择刚才创建的 App ID 选完点击 Continue

4、选择开发者证书如果有 For use in Xcode 11 or later 就选这个,选完点击 Continue

5、选择 允许安装 App 的设备,未勾选的将无法安装 App (选择 App Store 的无视),选完点击 Continue

6、填写描述文件名字,填写完点击 Generate

7、下载下载下载

创建秘钥

1、选择左边 Keys 栏目,创建用于客户端身份验证的私钥,点击 Create a Key

2、按下图步骤操作

3、选择 App ID 并保存

4、在 Register a New Key 页面点击 Continue

没错!这里没图

5、点击 Register

6、密钥仅能下载一次,下载的文件将以.p8结尾,建议将其重命名为key.txt以便在后续步骤中更轻松地使用

  1. After downloading your key, it cannot be re-downloaded as the server copy isremoved. If you are not prepared to download your key at this time, click Doneand download it at a later time. Be sure to save a backup of your key in a secure place.
  2. 下载密钥后,由于服务器副本已被删除,因此无法重新下载。如果此时您还没有准备好下载密钥,请单击Done,稍后再下载。请务必将您的密钥备份保存在安全的地方。

[
](http://www.wangquanwei.com/wp...

Key ID 在基于授权码的验证中会用到,具体见iOS 苹果授权登录(Sign in with Apple)系列之服务端篇

7.苹果授权登录Sign in with apple 之 PHP篇

在 iOS13 中,如果 App 提供第三方登录,就必须添加 苹果登录 Sign in with Apple 选项,并要求所有开发者于 2020年4月之前 完成现有应用的更新,否则审核不给通过。

iOS 苹果授权登录(Sign in with Apple)系列之Apple Developer配置篇

iOS 苹果授权登录(Sign in with Apple)系列之原生篇

iOS 苹果授权登录(Sign in with Apple)系列之uniapp篇

iOS 苹果授权登录(Sign in with Apple)系列之服务端篇

例子是基于 PHP 的 Laravel 框架进行开发,Java 平台可以参考 https://blog.csdn.net/wpf199402076118/article/details/99677412

苹果提供了两种验证方式,一种是基于 JWT 的算法验证,另外一种是基于 授权码 的验证,这里再提供第三种“取巧”的验证方式即“不验证模式”。

不验证模式

后端只需要接收App端提交的以下参数(user、email 为Apple返回给App的参数名)

user: 授权的用户唯一标识,该值在同一个开发者账号下的所有 App 下是一样的,开发者可以用该唯一标识符与自己后台系统的账号体系绑定起来

email: 邮箱,只有第一次 授权苹果才会给 App 返回邮箱信息,之后登录不再返回

fullName: 用户信息,只有第一次 授权苹果才会给 App 返回用户信息,之后登录不再返回

开发者只要判断 数据库 是否存在 user(授权的用户唯一标识) 存在就返回登录成功信息,不存在即在数据库插入 user、email、fullName等信息(业务逻辑根据具体需求调整)

教程到此结束,后面不用看了

验证模式

苹果授权登录(Sign in with Apple)后端验证
基于 JWT 的验证

Sign in with Apple 后端 JWT 验证文档:

https://developer.apple.com/documentation/signinwithapplerestapi/fetch_apple_s_public_key_for_verifying_token_signature

食用指南

后端只需要接收 App 端提交的以下参数(user、email 为Apple返回给App的参数名)

userID: 授权的用户唯一标识,该值在同一个开发者账号下的所有 App 下是一样的,开发者可以用该唯一标识符与自己后台系统的账号体系绑定起来

email: 邮箱,只有第一次 授权苹果才会给 App 返回邮箱信息,之后登录不再返回

fullName: 用户信息,只有第一次 授权苹果才会给 App 返回用户信息,之后登录不再返回

authorizationCode: 授权 code(没用到)

identityToken: 授权用户的 JWT 凭证

如何验证

1、安装 php-apple-signin 库

  1. composer require griffinledingham/php-apple-signin

需要 php7.2 及以上版本,如果低于该版本,自行修改源码,源码地址

  1. https://github.com/GriffinLedingham/php-apple-signin

2、验证 JWT

  1. public function jwtApple(Request $request) {
  2. // 授权的用户唯一标识
  3. $user \= $request->input('user');
  4. // 邮箱
  5. $email \= $request->input('email');
  6. // 用户信息
  7. $fullName \= $request->input('fullName');
  8. // 授权code 并没有用到
  9. $authorizationCode \= $request->input('authorizationCode');
  10. // 授权用户的JWT凭证
  11. $identityToken \= $request->input('identityToken');
  12. $appleSignInPayload \= ASDecoder::getAppleSignInPayload($identityToken);
  13. $isValid \= $appleSignInPayload->verifyUser($user);
  14. // 当 $isValid 为 true 时验证通过,后续逻辑根据需求编写
  15. dd($isValid);
  16. }
基于授权码的验证

Sign in with Apple 后端 授权码 验证文档:

https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens

其中 iss 和 kid 的获取方式

跑不通不知道哪里错了,等研究出来再更新

  1. {
  2. "error": "invalid_client"
  3. }

Demo

https://github.com/quanweiwang/sign-in-with-apple-server

你可能感兴趣的:(ios)