Files
webman-buildadmin-mall/scripts/playx-verify-token-callback-test.php

147 lines
4.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
/**
* 命令行模拟商城服务端调用 PLAYX_TOKEN_VERIFY_URL回调 verify-token
*
* 用法(在项目根目录执行):
* php scripts/playx-verify-token-callback-test.php "<playx_token>"
*
* 可选环境变量(未设置则从项目根 .env 读取):
* PLAYX_TOKEN_VERIFY_URL 默认 https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token
* PLAYX_ANGPOW_IMPORT_AUTH_KEY 与 angpow-imports 相同的 HMAC 密钥
*/
$root = dirname(__DIR__);
function loadDotEnv(string $path): void
{
if (!is_file($path)) {
return;
}
foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $line) {
$line = trim($line);
if ($line === '' || str_starts_with($line, '#')) {
continue;
}
if (!str_contains($line, '=')) {
continue;
}
$pos = strpos($line, '=');
$name = trim(substr($line, 0, $pos));
$value = trim(substr($line, $pos + 1));
if ($name !== '') {
$_ENV[$name] = $value;
putenv($name . '=' . $value);
}
}
}
function resolveKeyBytes(string $authKey): string
{
$maybeBase64 = base64_decode($authKey, true);
if (is_string($maybeBase64) && $maybeBase64 !== '') {
return $maybeBase64;
}
$isHex = ctype_xdigit($authKey) && (strlen($authKey) % 2 === 0);
if ($isHex) {
$hex = hex2bin($authKey);
if (is_string($hex) && $hex !== '') {
return $hex;
}
}
return $authKey;
}
function buildSignature(string $input, string $authKey): string
{
$raw = hash_hmac('sha1', $input, resolveKeyBytes($authKey), true);
return base64_encode($raw);
}
loadDotEnv($root . DIRECTORY_SEPARATOR . '.env');
$token = $argv[1] ?? '';
if ($token === '') {
fwrite(STDERR, "用法: php scripts/playx-verify-token-callback-test.php \"<playx_token>\"\n");
exit(1);
}
$url = strval($_ENV['PLAYX_TOKEN_VERIFY_URL'] ?? getenv('PLAYX_TOKEN_VERIFY_URL') ?: '');
if ($url === '') {
$url = 'https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token';
}
$authKey = strval($_ENV['PLAYX_ANGPOW_IMPORT_AUTH_KEY'] ?? getenv('PLAYX_ANGPOW_IMPORT_AUTH_KEY') ?: '');
if ($authKey === '') {
fwrite(STDERR, "缺少 PLAYX_ANGPOW_IMPORT_AUTH_KEY请在 .env 配置或导出环境变量)\n");
exit(1);
}
$requestId = 'mall_cli_' . uniqid();
$canonical = 'request_id=' . $requestId . '&token=' . $token;
$signature = buildSignature($canonical, $authKey);
$payload = json_encode([
'request_id' => $requestId,
'token' => $token,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($payload === false) {
fwrite(STDERR, "JSON 编码失败\n");
exit(1);
}
echo "--- 等价 curlLinux / macOS / Git Bash---\n";
echo "curl -sS -X POST '" . $url . "' \\\n";
echo " -H 'Content-Type: application/json' \\\n";
echo " -H 'X-Request-Signature: " . $signature . "' \\\n";
echo " -d '" . $payload . "'\n\n";
echo "--- 本机直接请求PHP stream---\n";
echo "request_id={$requestId}\n";
echo "canonical={$canonical}\n\n";
$body = $payload;
$ctx = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\nX-Request-Signature: {$signature}\r\n",
'content' => $body,
'timeout' => 15,
// 4xx/5xx 仍返回响应体,便于查看对端错误说明(否则 file_get_contents 直接 false
'ignore_errors' => true,
],
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
],
]);
$result = @file_get_contents($url, false, $ctx);
if ($result === false) {
$err = error_get_last();
fwrite(STDERR, "请求失败: " . ($err['message'] ?? 'unknown') . "\n");
exit(1);
}
$statusLine = isset($http_response_header[0]) ? $http_response_header[0] : '';
echo "--- HTTP 响应行 ---\n";
echo $statusLine . "\n";
if (isset($http_response_header[1])) {
echo "--- 响应头(节选)---\n";
$max = min(12, count($http_response_header));
for ($i = 1; $i < $max; $i++) {
echo $http_response_header[$i] . "\n";
}
}
echo "--- 响应体 ---\n";
echo $result . "\n";
if (!preg_match('/\b200\b/', $statusLine)) {
fwrite(STDERR, "\n提示:非 2xx 时请根据响应体与对端核对签名字符串、Body 字段是否与回调网关约定一致。\n");
exit(2);
}