苹果授权登陆方式
第一种: PC/M端授权登陆,采用协议类似于oauth2协议,服务端基于授权码验证
第二种: App端授权登陆,服务端基于JWT的算法验证
第一种方式的验证流程
1 首先获取code:GET
https://appleid.apple.com/auth/authorize?response_type=code&client_id=https://www.xxx.com/getcode&redirect_uri=&state=12345
参考后台配置,其中client_id对应的是Services ID,redirect_uri就是后台配置的接收code码的地址
用户授权后会跳转到redirect_uri,https://www.xxx.com/getcode?state=12345&code=c5a5a78a1b32b44b68431923aa067dd9d.0.rrzyu.ETY9UozOD10dx0FzFPpcbw
code有效期5分钟
2 根据code获取token:POST
发送请求:
public function generateRefreshToken($clientId, $clientSecret, $code)
{
$params = [
'client_id' => $clientId,
'client_secret' => $clientSecret,//jwt格式生成,后面单独讲述
'code' => $code,
'grant_type' => 'authorization_code',
];
$resp = Utils::curl('https://appleid.apple.com/auth/token', $params, [
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_TIMEOUT => 10,
]);
$ret = json_decode($resp, true);
return $ret;
}
返回结果:
{
"access_token": "adg61...67Or9",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "rca7...lABoQ",
"id_token": "eyJra...96sZg"
}
3 根据refresh_token刷新(生成)新的access_token
发送请求:
public function getAccessToken($clientId, $refreshToken, $clientSecret)
{
$params = [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
];
$resp = Utils::curl('https://appleid.apple.com/auth/token', $params, [
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_TIMEOUT => 10,
]);
$ret = json_decode($resp, true);
return $ret;
}
返回结果:
{
"access_token": "beg510...67Or9",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJra...96sZg"
}
4 对id-token进行jwt验证解密
后面章节对id-token进行解密进行单独阐述
第二种方式的登录流程
关于手机端登录的代码,这里不做多余介绍,我们看下登录成功后, Apple 返回给手机端的一些参数。
open var user: String { get }
open var state: String? { get }
open var authorizedScopes: [ASAuthorization.Scope] { get }
open var authorizationCode: Data? { get }
open var identityToken: Data? { get }
open var email: String? { get }
open var fullName: PersonNameComponents? { get }
open var realUserStatus: ASUserDetectionStatus
登录成功后,从 Apple 拿到 :user、email、fullName、authorizationCode、identityToken 。
- userID:授权的用户唯一标识
- email、fullName:授权的用户资料
- authorizationCode:授权code。(授权code是有时效性的,且使用一次即失效)
- identityToken:授权用户的JWT凭证
对于APP一般是基于JWT的算法验证
APP上传userID
、identityToken
,服务端解析identityToken
获取用户唯一标识与userID
进行对比。
服务端解析identityToken
的步骤跟下面3、解码id_token
是一样的。
当然也可以基于授权码的验证,验证的方式就类似于上面的流程1了。
- 首先需要得到
client_secret
。 - 根据APP上传上来的
authorizationCode
请求苹果服务器进行登录,获取id_token
。 - 解析
id_token
,获取用户唯一标识。
文章评论