帝国CMS模板大全
www.admin99.cn
www.92cms.cn 帝国CMS模板下载站!,情怀,养站,二次开发!源码需求比较大的一站式会员下载,价更省!!!

原生PHP实现支付宝App第三方登录获取用户信息

背景

App 项目要求实现第三方 微信 和 支付宝 登录,微信可以直接在 App 端完成认证拿到用户信息,支付宝则需要后端获取。

流程

1、服务端先拿到 App 端 调用 支付宝 SDK 所需要的 infoStr

2、App 端 通过 infoStr 获得用户 授权 code

3、服务端通过 授权 code 拿到请求 token

4、服务端通过 token 获得用户信息

代码

在这之前,支付宝接口对接流程你应该有所了解。

1、创建 RSA2 方法:获得 sign:

/**
 * enRSA2 RSA加密
 * 
 * @param String $data
 * @return String
 */
private function enRSA2($data)
{
    $str = chunk_split(trim($this->private_key), 64, "\n");
    $key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
    // $key = file_get_contents(storage_path('rsa_private_key.pem')); 为文件时这样引入
    $signature = '';
    $signature = openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA256)?base64_encode($signature):NULL;
    return $signature;
}

2、创建一个 Get 参数拼接方法,保证符合支付宝加签字符串要求:

/**
 * myHttpBuildQuery
 * 之所以不用 自带函数 `http_build_query` 
 * 是因为格式化的时间带有  ‘:’  会被转换成十六进制 utf-8 码
 * 
 * @param Array
 * @return String
 */
private function myHttpBuildQuery($dataArr)
{
    ksort($dataArr);
    $signStr = '';
    foreach ($dataArr as $key => $val) {
   if (empty($signStr)) {
  $signStr = $key.'='.$val;
   } else {
  $signStr .= '&'.$key.'='.$val;
   }
    }
    return $signStr;  
}

3、给到 APP 端需要的 infoStr:

/**
 * InfoStr APP登录需要的的infostr
 * 
 * @return String
 */
public function infoStr()
{
    $infoStr = http_build_query([
   'apiname' => 'com.alipay.account.auth',
   'method' => 'alipay.open.auth.sdk.code.get',
   'app_id' => $this->app_id,
   'app_name' => 'mc',
   'biz_type' => 'openservice',
   'pid' => $this->pid,
   'product_id' => 'APP_FAST_LOGIN',
   'scope' => 'kuaijie',
   'target_id' => mt_rand(999, 99999), //商户标识该次用户授权请求的ID,该值在商户端应保持唯一
   'auth_type' => 'AUTHACCOUNT', // AUTHACCOUNT代表授权;LOGIN代表登录
   'sign_type' => 'RSA2',
    ]);
    $infoStr .= '&sign='.$this->enRSA2($infoStr);
    return $infoStr;
}

4、拿到用户信息:

 /**
* AlipayToken 获得用户 请求token, 通过它获得 用户信息
* 
* 需要按照支付宝加签流程来。
*/
    public function userInfo($app_auth_token)
    {
   $infoArr = [
  'method' => 'alipay.system.oauth.token',
  'app_id' => $this->app_id,
  'charset' => 'utf-8',
  'sign_type' => 'RSA2',
  'timestamp' => date('Y-m-d H:i:s'),
  'version' => '1.0',
  'code' => $app_auth_token,
  'grant_type' => 'authorization_code',
   ];
   $signStr = $this->myHttpBuildQuery($infoArr);
   $sign = urlencode($this->enRSA2($signStr));
   $qureStr = $signStr.'&sign='.$sign;
   $res = new Client();
   $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
   $body = json_decode($body);
   if (!isset($body->alipay_system_oauth_token_response->access_token)) {
  return '接口异常';
   } else {
  $autho_token = $body->alipay_system_oauth_token_response->access_token;
  $userinfo = $this->aliPayUserInfo($autho_token);
  return $userinfo; // 或则 返回 json_encode($userinfo) 根据实际需求来 
   }
    }
    /**
* AliPayUserInfo 通过 token 获取用户信息
*/
    private function aliPayUserInfo($autho_token)
    {
   $infoArr = [
  'method' => 'alipay.user.info.share',
  'app_id' => $this->app_id,
  'charset' => 'utf-8',
  'sign_type' => 'RSA2',
  'timestamp' => date('Y-m-d H:i:s'),
  'version' => '1.0',
  'auth_token' => $autho_token,
   ];
   $signStr = $this->myHttpBuildQuery($infoArr);
   $sign = urlencode($this->enRSA2($signStr));
   $qureStr = $signStr.'&sign='.$sign;
   $res = new Client();
   $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
   $body = json_decode($body);
   if (!isset($body->alipay_user_info_share_response)) {
  return '接口异常';
   }
   $body = $body->alipay_user_info_share_response;
   return $body;
    }

代码总览

<?php 
// 使用 Guzzle 做请求操作
use GuzzleHttp\Client;
// 支付宝APP 第三方登录
// 特点:相比微信,支付宝所有敏感信息都在服务端完成, 保证了安全
//
// 流程:
// 1.服务端到APP infoStr 
// 2.APP端 通过infoStr 获得 auth_code 
// 3.服务端通过 auth_code 拿到请求 token
// 4.服务端通过 token 获得用户信息
class AliPayUser{
    protected $app_id = '支付宝app_id';
    protected $pid = '支付宝pid';
    protected $private_key = '你的私钥';
    /**
* InfoStr APP登录需要的的infostr
* 
* @return String
*/
    public function infoStr()
    {
   $infoStr = http_build_query([
  'apiname' => 'com.alipay.account.auth',
  'method' => 'alipay.open.auth.sdk.code.get',
  'app_id' => $this->app_id,
  'app_name' => 'mc',
  'biz_type' => 'openservice',
  'pid' => $this->pid,
  'product_id' => 'APP_FAST_LOGIN',
  'scope' => 'kuaijie',
  'target_id' => mt_rand(999, 99999), //商户标识该次用户授权请求的ID,该值在商户端应保持唯一
  'auth_type' => 'AUTHACCOUNT', // AUTHACCOUNT代表授权;LOGIN代表登录
  'sign_type' => 'RSA2',
   ]);
   $infoStr .= '&sign='.$this->enRSA2($infoStr);
   return $infoStr;
    }
/**
* AlipayToken 获得用户 请求token, 通过它获得 用户信息
* 
* 需要按照支付宝加签流程来。
*/
    public function userInfo($app_auth_token)
    {
   $infoArr = [
  'method' => 'alipay.system.oauth.token',
  'app_id' => $this->app_id,
  'charset' => 'utf-8',
  'sign_type' => 'RSA2',
  'timestamp' => date('Y-m-d H:i:s'),
  'version' => '1.0',
  'code' => $app_auth_token,
  'grant_type' => 'authorization_code',
   ];
   $signStr = $this->myHttpBuildQuery($infoArr);
   $sign = urlencode($this->enRSA2($signStr));
   $qureStr = $signStr.'&sign='.$sign;
   $res = new Client();
   $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
   $body = json_decode($body);
   if (!isset($body->alipay_system_oauth_token_response->access_token)) {
  return '接口异常';
   } else {
  $autho_token = $body->alipay_system_oauth_token_response->access_token;
  $userinfo = $this->aliPayUserInfo($autho_token);
  return $userinfo; // 或则 返回 json_encode($userinfo) 根据实际需求来 
   }
    }
    /**
* AliPayUserInfo 通过 token 获取用户信息
*/
    private function aliPayUserInfo($autho_token)
    {
   $infoArr = [
  'method' => 'alipay.user.info.share',
  'app_id' => $this->app_id,
  'charset' => 'utf-8',
  'sign_type' => 'RSA2',
  'timestamp' => date('Y-m-d H:i:s'),
  'version' => '1.0',
  'auth_token' => $autho_token,
   ];
   $signStr = $this->myHttpBuildQuery($infoArr);
   $sign = urlencode($this->enRSA2($signStr));
   $qureStr = $signStr.'&sign='.$sign;
   $res = new Client();
   $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
   $body = json_decode($body);
   if (!isset($body->alipay_user_info_share_response)) {
  return '接口异常';
   }
   $body = $body->alipay_user_info_share_response;
   return $body;
    }
    /**
* enRSA2 RSA加密
* 
* @param String $data
* @return String
*/
    private function enRSA2($data)
    {
   $str = chunk_split(trim($this->private_key), 64, "\n");
   $key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
   // $key = file_get_contents(storage_path('rsa_private_key.pem')); 为文件时这样引入
   $signature = '';
   $signature = openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA256)?base64_encode($signature):NULL;
   return $signature;
    }
    /**
* myHttpBuildQuery 返回一个 http Get 传参数组
* 之所以不用 自带函数 http_build_query 时间带 ‘:’ 会被转换
* 
* @param Array
* @return String
*/
    private function myHttpBuildQuery($dataArr)
    {
   ksort($dataArr);
   $signStr = '';
   foreach ($dataArr as $key => $val) {
  if (empty($signStr)) {
 $signStr = $key.'='.$val;
  } else {
 $signStr .= '&'.$key.'='.$val;
  }
   }
   return $signStr;  
    }
}

其它

1.注意:这份代码是从原有项目扒出来,主要是为有此需求的开发人员提供参考,并未测试是否能直接使用,请自行测试。

2.之所以不用支付宝 php_SDK,是因为需求有限:只获取用户的信息,没必要。

3.代码有不合理的地方还请提出来,大家互相学习。

以上就是原生 PHP 实现支付宝 App 第三方登录获取用户信息的详细内容,更多请关注Gxl网其它相关文章!

赞(0)
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《原生PHP实现支付宝App第三方登录获取用户信息》
文章链接:https://www.admin99.cn/4475
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
QQ站长交流群:953950264

登录

找回密码

注册