app中要接入apple账号的第三方登录,这里只记录后端的东西,app中获取数据的过程是由前端小哥搞定的,后端的验证步骤一共三步
- 检查appleId是否在本地注册了,已经注册过就自动登录,否则通过apple提供的接口进行签名的校验并在本地第三方表中注册appleId
- appleId与用户主表进行关联绑定
- 进行登录操作
登录过程用到了两张表,一张是user,用户主表,里边存放的是用户的信息,如mobile、nickname等,我们的用户信息是通过mobile来进行唯一性判定的,另外一张表是user_apple,里边存放的是前端传过来的苹果用户信息,有苹果的唯一标识、名字、邮箱等信息,
在接入过程中需要对前台传递的apple签名进行校验,所以我从网上找了一个扩展包,在做签名校验的时候使用,我用的yii,就以yii为例,扩展包地址https://github.com/GriffinLedingham/php-apple-signin,可以直接composer安装,命令如下:
composer require wubuwei/php-apple-signin
我这边不知道是什么原因,就是下载不了,切换了阿里云的composer镜像也不行,所以只好手动安装啦,把扩展包手动下载完了之后放到vendor文件夹下边,然后需要引入一下命名空间,不然不能使用,在common下的配置文件main.php中加入如下代码就可以了
[
'aliases' => [
'@AppleSignIn' => '@vendor/wubuwei/php-apple-signin',
],
]
//"@AppleSignIn"就是命名空间,"@vendor/wubuwei/php-apple-signin"是文件的路径
下边是第一个接口的代码,作用是检查appleId和对appleId进行本地注册
use AppleSignIn\ASDecoder;
use common\classes\Service\ParamsValidateService;
/**
* 苹果账号登录
* 苹果账号登录
* @api POST /v1/user/login-by-apple
* @param string access_token token
* @param string openid 用户标识
* @param string familyName familyName
* @param string giveName giveName
* @param string givenName givenName
* @param string email email
* @return string $message 状态说明
* @return mixed $data 其他数据
*/
public function actionLoginByApple()
{
$PVS = new ParamsValidateService();
$data=\Yii::$app->request->post();
$valid = $PVS->validate($data, [
[['access_token','openid'], 'required'],
[['access_token','openid','familyName','giveName','givenName','email'], 'string'],
]);
if (!$valid) return $this->returnData(0, '数据参数错误', $PVS->getErrorSummary(true));
$ip = Yii::$app->request->getUserIP();
$userApple = UserApple::findOne(['openid'=>$data['openid']]);
if($userApple && $userApple->uid){
$userInfo = User::findOne($userApple->uid);
if(!$userInfo) return $this->returnData(1, '数据错误',$userInfo);
$res = User::LoginReuslt($userInfo);
if($res){
User::updateData(array('last_login_time' => time()),$userInfo->id);
return $this->returnData(1, '注册成功',$res);
}else{
return $this->returnData(0, '操作失败,请稍后再试!');
}
}
try{
$appleSignInPayload = ASDecoder::getAppleSignInPayload($data['access_token']);
$check = $appleSignInPayload->verifyUser($data['openid']);
if(!$check) throw new \Exception("签名认证失败");
$model = new UserApple();
$model->openid = $data['openid'];
$model->createtime = time();
$model->ip = $ip;
$model->family_name = isset($data['familyName'])?$data['familyName']:'';
$model->give_name = isset($data['giveName'])?$data['giveName']:'';
$model->given_name = isset($data['givenName'])?$data['givenName']:'';
$model->email = isset($data['email'])?$data['email']:'';
$model->save();
$errors = $model->getErrors();
if($errors) throw new \Exception(json_encode($errors));
}catch (\Exception $e){
return $this->returnData(0, '登录失败', $e->getMessage());
}
return $this->returnData(2, '请绑定用户',[]);
}
然后是appleId与用户表进行关联
/**
* 苹果账号关联用户
* 苹果账号关联用户
* @api POST /v1/user/apple-associated-user
* @param string mobile 用户手机号
* @param string openid 用户标识
* @return mixed $data 其他数据
*/
public function appleAssociatedUser($data)
{
$time = time();
$userApple = UserApple::findOne(['openid'=>$data['openid']]);
if(!$userApple){
return [
'status'=>0,
'data'=>'请先进行苹果授权'
];
}
if($userApple->uid) {
return [
'status'=>0,
'data'=>'已经关联过用户了'
];
}
$user = User::findOne(['mobile'=>$data['mobile']]);
if(!$user){
$ip = Yii::$app->request->getUserIP();
$user = new User();
$user->mobile = $data['mobile'];
$user->username = $userApple->family_name.$userApple->give_name;
$user->nickname = $userApple->give_name;
$user->status = 1;
$user->last_login_time = $time;
$user->created = $time;
$user->last_login_ip = $ip;
$user->save();
$errors = $user->getErrors();
if($errors){
return [
'status'=>0,
'data'=>json_encode($errors)
];
}
}
$userApple->uid = $user->id;
$userApple->save();
$errors = $userApple->getErrors();
if($errors){
return [
'status'=>0,
'data'=>json_encode($errors)
];
}
return [
'status'=>1,
'data'=>'',
];
}