您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關原生 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 第三方登錄獲取用戶信息的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。