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

互联网 19-8-22
背景

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;   }
/**  * 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 第三方登录获取用户信息的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: PHP
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:php八大数据类型有哪些

相关资讯