|
|
@@ -2,6 +2,7 @@
|
|
|
namespace common\components\delivery\platform\dada;
|
|
|
|
|
|
use common\components\delivery\helpers\HttpClient;
|
|
|
+use common\components\util;
|
|
|
use Yii;
|
|
|
|
|
|
/**
|
|
|
@@ -38,7 +39,7 @@ class Auth
|
|
|
*/
|
|
|
public function __construct()
|
|
|
{
|
|
|
- $isProduction = getenv('YII_ENV') == 'dev';
|
|
|
+ $isProduction = getenv('YII_ENV') == 'dev'; // TODO
|
|
|
|
|
|
if ($isProduction) {
|
|
|
// 生产环境配置(需要替换为实际的生产环境凭证)
|
|
|
@@ -87,14 +88,52 @@ class Auth
|
|
|
$params = [
|
|
|
'appKey' => $this->appKey,
|
|
|
'nonce' => $nonce,
|
|
|
- 'sign' => strtoupper($sign),
|
|
|
+ 'sign' => $sign,
|
|
|
];
|
|
|
|
|
|
// 发送 GET 请求
|
|
|
- $url = $this->authorizeUrl . 'third/party/ticket';// . '?' . http_build_query($params);
|
|
|
+ $url = $this->authorizeUrl . 'third/party/ticket';
|
|
|
|
|
|
try {
|
|
|
- $resp = HttpClient::get($url, $params); // $params
|
|
|
+ // 构建完整请求 URL
|
|
|
+ $requestUrl = $url;
|
|
|
+ if (!empty($params)) {
|
|
|
+ $requestUrl .= '?' . http_build_query($params);
|
|
|
+ }
|
|
|
+ Yii::info("\n\n\n\n\n\nrequestUrl: " . $requestUrl);
|
|
|
+
|
|
|
+ // 初始化 cURL
|
|
|
+ $ch = curl_init();
|
|
|
+
|
|
|
+ // 设置选项
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $requestUrl);
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
+ curl_setopt($ch, CURLOPT_HEADER, false);
|
|
|
+ curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
|
+ 'Content-Type: application/json'
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 执行请求
|
|
|
+ $response = curl_exec($ch);
|
|
|
+ $error = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ // 检查错误
|
|
|
+ if ($error) {
|
|
|
+ throw new \Exception('cURL Request Error: ' . $error);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析响应
|
|
|
+ $resp = json_decode($response, true);
|
|
|
+ if (json_last_error() !== JSON_ERROR_NONE) {
|
|
|
+ // 如果解析失败,可能是非 JSON 响应
|
|
|
+ // throw new \Exception('Invalid JSON Response: ' . $response);
|
|
|
+ Yii::error('Invalid JSON Response: ' . $response);
|
|
|
+ util::fail('请求达达获取ticket失败');
|
|
|
+ }
|
|
|
|
|
|
// 检查响应状态,返回 ticket
|
|
|
if (isset($resp['result']) && !empty($resp['result'])) {
|
|
|
@@ -137,33 +176,73 @@ class Auth
|
|
|
'appSecret' => $this->appSecret,
|
|
|
];
|
|
|
|
|
|
- // 第一步:按键排序
|
|
|
- ksort($signParams);
|
|
|
- // 第一步:按值排序且不改变key
|
|
|
+ // 第一步
|
|
|
+ // 按键排序
|
|
|
+ //ksort($signParams, SORT_STRING);
|
|
|
+ // 按值排序且不改变key
|
|
|
//asort($signParams);
|
|
|
- //sort($signParams, SORT_STRING);
|
|
|
+ sort($signParams, SORT_STRING);
|
|
|
|
|
|
|
|
|
// 第二步:拼接所有参数值
|
|
|
$signString = implode('', $signParams);
|
|
|
- //$signString = $signString . $this->appSecret;
|
|
|
+
|
|
|
// 第二步:拼接 key 和 value
|
|
|
-// $signString = '';
|
|
|
-// foreach ($signParams as $key => $value) {
|
|
|
-// $signString .= $key . $value;
|
|
|
-// }
|
|
|
-// $signString = $signString . 'appSecret' . $this->appSecret;
|
|
|
+ // $signString = '';
|
|
|
+ // foreach ($signParams as $key => $value) {
|
|
|
+ // $signString .= $key . $value;
|
|
|
+ // }
|
|
|
+ // $signString = $signString;
|
|
|
|
|
|
// 第三步:SHA1 加密
|
|
|
$hex = sha1($signString);
|
|
|
|
|
|
- $len = 36;
|
|
|
- if ($len < strlen($hex)) {
|
|
|
- $hex = substr($hex, 0, $len);
|
|
|
- }
|
|
|
+ // $len = 36;
|
|
|
+ // if ($len < strlen($hex)) {
|
|
|
+ // $hex = substr($hex, 0, $len);
|
|
|
+ // }
|
|
|
+
|
|
|
+ //return strtoupper(substr($hex, 0, 36));
|
|
|
+ //return strtoupper($hex);
|
|
|
return $hex;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 生成获取授权码请求的签名
|
|
|
+ *
|
|
|
+ * 签名算法:
|
|
|
+ * 1. 参与签名的参数值按字典排序:appKey、appSecret、nonce
|
|
|
+ * 2. 拼接参数值
|
|
|
+ * 3. SHA1 加密
|
|
|
+ *
|
|
|
+ * @param string $nonce 随机数
|
|
|
+ * @return string SHA1 签名
|
|
|
+ */
|
|
|
+ function generateTicketSign_234($nonce)
|
|
|
+ {
|
|
|
+ // 1. 按字段名升序拼接
|
|
|
+ $map = [
|
|
|
+ 'appKey' => $this->appKey,
|
|
|
+ 'appSecret' =>$this->appSecret,
|
|
|
+ 'nonce' => $nonce,
|
|
|
+ ];
|
|
|
+ ksort($map, SORT_STRING); // 按 key 升序
|
|
|
+
|
|
|
+ $raw = '';
|
|
|
+ foreach ($map as $k => $v) {
|
|
|
+ $raw .= $k . $v; // 不要加 & = 空格
|
|
|
+ }
|
|
|
+ //$raw = implode('', $map);
|
|
|
+
|
|
|
+ // 2. SHA1 得到 40 位 16 进制(小写)
|
|
|
+ $sha1 = sha1($raw, false); // 第二个参数=false 返回十六进制字符串
|
|
|
+
|
|
|
+ // 3. 转大写 + 截前 36 位
|
|
|
+ //return strtoupper(substr($sha1, 0, 36));
|
|
|
+ return strtoupper($sha1);
|
|
|
+ return sha1($raw);
|
|
|
+ }
|
|
|
+
|
|
|
private function newGenerateTicketSign($nonce)
|
|
|
{
|
|
|
// 参与签名的参数
|
|
|
@@ -223,7 +302,7 @@ class Auth
|
|
|
$nonce = $this->generateNonce();
|
|
|
|
|
|
// 生成签名
|
|
|
- $sign = $this->generateSign($ticket, $nonce, $shopId);
|
|
|
+ $sign = $this->generateAuthSign($ticket, $nonce, $shopId);
|
|
|
|
|
|
// 构建授权链接参数
|
|
|
$params = [
|
|
|
@@ -246,6 +325,30 @@ class Auth
|
|
|
|
|
|
return $this->authorizeUrl . 'third/party/oauth' . '?' . http_build_query($params);
|
|
|
}
|
|
|
+
|
|
|
+ private function generateAuthSign($ticket, $nonce, $shopId = '')
|
|
|
+ {
|
|
|
+ // 参与签名的参数
|
|
|
+ $signParams = [
|
|
|
+ 'appKey' => $this->appKey,
|
|
|
+ 'ticket' => $ticket,
|
|
|
+ 'nonce' => $nonce,
|
|
|
+ 'appSecret' => $this->appSecret,
|
|
|
+ ];
|
|
|
+
|
|
|
+ if($shopId!=''){
|
|
|
+ $signParams['shopId'] = $shopId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第一步
|
|
|
+ sort($signParams, SORT_STRING);
|
|
|
+ // 第二步:拼接所有参数值
|
|
|
+ $signString = implode('', $signParams);
|
|
|
+ // 第三步:SHA1 加密
|
|
|
+ $hex = sha1($signString);
|
|
|
+
|
|
|
+ return $hex;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 生成随机数(nonce)
|