Browse Source

新增火山临时token接口

lh 6 hours ago
parent
commit
d04814cf79

+ 1 - 0
app/Console/Test/TestCommand.php

@@ -6,6 +6,7 @@ use App\Cache\UserCache;
 use App\Facade\Site;
 use App\Libs\TikTok\Kernel\Support\Str;
 use App\Services\DeepSeek\DeepSeekService;
+use GuzzleHttp\Client;
 use Illuminate\Console\Command;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Redis;

+ 7 - 0
app/Http/Controllers/DeepSeek/DeepSeekController.php

@@ -59,4 +59,11 @@ class DeepSeekController extends BaseController
         $result = $this->deepseekService->addGenerateTask($data);
         return $this->success(['success'=>$result ? 1 : 0]);
     }
+
+    // 获取火山临时token
+    public function setStsToken(Request $request) {
+        $data = $request->all();
+        $result = $this->deepseekService->setStsToken($data);
+        return $this->success($result);
+    }
 }

+ 137 - 0
app/Services/DeepSeek/DeepSeekService.php

@@ -6,6 +6,8 @@ use App\Consts\ErrorConst;
 use App\Facade\Site;
 use App\Libs\Utils;
 use GuzzleHttp\Client;
+use DateTime;
+use DateTimeZone;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Redis;
 use OSS\Core\OssException;
@@ -211,6 +213,141 @@ class DeepSeekService
         return $list;
     }
 
+    // 生成火山临时token
+    public function setStsToken() {
+        // ************* 配置参数 *************
+        $method = 'GET';
+        $service = 'sts';
+        $host = 'open.volcengineapi.com';
+        $region = env('VOLC_REGION');
+        $endpoint = 'https://open.volcengineapi.com';
+        // $endpoint = 'https://tos-cn-beijing.volces.com';
+        $access_key = env('VOLC_AK');
+        $secret_key = env('VOLC_SK');
+
+        // 获取缓存中的token,如果没有则请求接口
+        $token = Redis::get('volc_sts_token');
+        if (!$token) {
+            // 查询参数
+            $query_parameters = [
+                'Action' => 'AssumeRole',
+                'RoleSessionName' => 'user@zw',
+                'RoleTrn' => 'trn:iam::2102575520:role/tos_role',
+                'Version' => '2018-01-01'
+            ];
+
+            // 生成URL编码的查询字符串
+            $request_parameters = http_build_query($query_parameters, '', '&', PHP_QUERY_RFC3986);
+
+            // 获取签名头信息
+            $headers = $this->getSignHeaders($method, $service, $host, $region, $request_parameters, $access_key, $secret_key);
+
+            // 构建完整URL
+            $request_url = $endpoint . '?' . $request_parameters;
+
+            $client = new Client(['verify' => false]);
+            $response = $client->get($request_url, ['headers' => $headers]);
+            $response_arr = json_decode($response->getBody()->getContents(), true);
+
+            $result = [
+                'SessionToken'      => isset($response_arr['Result']['Credentials']['SessionToken']) ? $response_arr['Result']['Credentials']['SessionToken'] : '',
+                'AccessKeyId'       => isset($response_arr['Result']['Credentials']['AccessKeyId']) ? $response_arr['Result']['Credentials']['AccessKeyId'] : '',
+                'SecretAccessKey'   => isset($response_arr['Result']['Credentials']['SecretAccessKey']) ? $response_arr['Result']['Credentials']['SecretAccessKey'] : '',
+                'Region'            => env('VOLC_REGION'),
+                'Endpoint'          => env('VOLC_END_POINT'),
+                'Bucket'            => env('VOLC_BUCKET'),
+            ];
+
+            // 缓存token
+            Redis::setex('volc_sts_token', 3000, json_encode($result));
+            return $result;
+        } else {
+            return json_decode($token, true);
+        }
+        
+        // $response = $response['Response'];
+        // $access_key = $response['Credentials']['AccessKeyId'];
+        // $secret_key = $response['Credentials']['AccessKeySecret'];
+        // $security_token = $response['Credentials']['SecurityToken'];
+        // $expiration = $response['Credentials']['Expiration'];
+        // dd($response_arr);
+    }
+
+    private function sign($key, $msg) {
+        return hash_hmac('sha256', $msg, $key, true);
+    }
+   
+    // 生成签名密钥
+    private function getSignatureKey($key, $dateStamp, $regionName, $serviceName) {
+        $kDate = $this->sign($key, $dateStamp);
+        $kRegion = $this->sign($kDate, $regionName);
+        $kService = $this->sign($kRegion, $serviceName);
+        $kSigning = $this->sign($kService, 'request');
+        return $kSigning;
+    }
+
+    // 获取签名头信息
+    private function getSignHeaders($method, $service, $host, $region, $request_parameters, $access_key, $secret_key) {
+        $contenttype = 'application/x-www-form-urlencoded';
+        $accept = 'application/json';
+        
+        // 获取当前UTC时间
+        $t = new DateTime('now', new DateTimeZone('UTC'));
+        $xdate = $t->format('Ymd\THis\Z');
+        $datestamp = $t->format('Ymd');
+        
+        // 1. 拼接规范请求串
+        $canonical_uri = '/';
+        $canonical_querystring = $request_parameters;
+        $canonical_headers = "content-type:{$contenttype}\nhost:{$host}\nx-date:{$xdate}\n";
+        $signed_headers = 'content-type;host;x-date';
+        
+        // 空请求体的SHA256哈希
+        $payload_hash = hash('sha256', '');
+        
+        $canonical_request = implode("\n", [
+            $method,
+            $canonical_uri,
+            $canonical_querystring,
+            $canonical_headers,
+            $signed_headers,
+            $payload_hash
+        ]);
+        
+        // 2. 拼接待签名字符串
+        $algorithm = 'HMAC-SHA256';
+        $credential_scope = implode('/', [$datestamp, $region, $service, 'request']);
+        $hashed_canonical_request = hash('sha256', $canonical_request);
+        
+        $string_to_sign = implode("\n", [
+            $algorithm,
+            $xdate,
+            $credential_scope,
+            $hashed_canonical_request
+        ]);
+        
+        // 3. 计算签名
+        $signing_key = $this->getSignatureKey($secret_key, $datestamp, $region, $service);
+        $signature = hash_hmac('sha256', $string_to_sign, $signing_key);
+        
+        // 4. 添加签名到请求头
+        $authorization_header = sprintf(
+            '%s Credential=%s/%s, SignedHeaders=%s, Signature=%s',
+            $algorithm,
+            $access_key,
+            $credential_scope,
+            $signed_headers,
+            $signature
+        );
+        
+        return [
+            'Accept' => $accept,
+            'Content-Type' => $contenttype,
+            'X-Date' => $xdate,
+            'Authorization' => $authorization_header
+        ];
+    }
+
     // 文字合成语音(火山引擎)
     public function tts($data) {
         $url = 'https://openspeech.bytedance.com/api/v1/tts';

+ 1 - 0
routes/api.php

@@ -37,6 +37,7 @@ Route::group(['middleware' => ['bindToken', 'bindExportToken', 'checkLogin']], f
         Route::post('chatWithReasoner', [DeepSeekController::class, 'chatWithReasoner']);
         Route::get('timbreList', [DeepSeekController::class, 'timbreList']);
         Route::post('addGenerateTask', [DeepSeekController::class, 'addGenerateTask']);
+        Route::get('setStsToken', [DeepSeekController::class, 'setStsToken']);
     });
     
 });