1.远程验证token有效性

This commit is contained in:
2026-04-30 14:25:36 +08:00
parent 8017d1819a
commit cf6aa7e9e9
2 changed files with 69 additions and 3 deletions

View File

@@ -32,6 +32,12 @@ PLAYX_PARTNER_JWT_SECRET=
AGENT_AUTH_JWT_SECRET= AGENT_AUTH_JWT_SECRET=
# token 会话缓存过期时间(秒) # token 会话缓存过期时间(秒)
PLAYX_SESSION_EXPIRE_SECONDS=3600 PLAYX_SESSION_EXPIRE_SECONDS=3600
# verifyToken 是否仅本地联调false=走对方远程校验)
PLAYX_VERIFY_TOKEN_LOCAL_ONLY=false
# verifyToken 仅本地联调时的默认用户ID
PLAYX_VERIFY_TOKEN_LOCAL_DEFAULT_USER_ID=testmyr
# verifyToken 仅本地联调时的默认用户名
PLAYX_VERIFY_TOKEN_LOCAL_DEFAULT_USERNAME=yangyang123
# PlayX API商城调用 PlayX 时使用) # PlayX API商城调用 PlayX 时使用)
PLAYX_API_BASE_URL= PLAYX_API_BASE_URL=
PLAYX_API_SECRET_KEY= PLAYX_API_SECRET_KEY=

View File

@@ -411,21 +411,47 @@ class Playx extends Api
return $this->error(__('Token expiration'), null, 0, ['statusCode' => 401]); return $this->error(__('Token expiration'), null, 0, ['statusCode' => 401]);
} }
$baseUrl = config('playx.api.base_url', ''); $baseUrl = config('playx.angpow_import.base_url', '');
$verifyUrl = config('playx.api.token_verify_url', '/api/v1/auth/verify-token'); $verifyUrl = config('playx.api.token_verify_url', '/api/v1/auth/verify-token');
if ($baseUrl === '') { if ($baseUrl === '') {
return $this->error(__('PlayX API not configured')); return $this->error(__('PlayX API not configured'));
} }
try { try {
$merchantCode = strval(config('playx.angpow_import.merchant_code', ''));
$authKey = strval(config('playx.angpow_import.auth_key', ''));
if ($merchantCode === '' || $authKey === '') {
return $this->error(__('PlayX API not configured'));
}
$requestId = 'mall_' . uniqid();
$requestDate = gmdate('Y-m-d H:i:s');
$signatureInput = 'merchant_code=' . $merchantCode
. '&request_date=' . $requestDate
. '&request_id=' . $requestId
. '&token=' . $token;
$signature = $this->buildPlayxTokenVerifySignature($signatureInput, $authKey);
if ($signature === null) {
return $this->error(__('Invalid signature'), null, 0, ['statusCode' => 500]);
}
$client = new \GuzzleHttp\Client([ $client = new \GuzzleHttp\Client([
'base_uri' => rtrim($baseUrl, '/') . '/', 'base_uri' => rtrim($baseUrl, '/') . '/',
'timeout' => 10, 'timeout' => 10,
]); ]);
$res = $client->post($verifyUrl, [ $res = $client->post($verifyUrl, [
'headers' => [
'Content-Type' => 'application/json',
'X-Request-Signature' => $signature,
'X-Signature' => $signature,
'X-Request-Date' => $requestDate,
'X-Request-ID' => $requestId,
],
'json' => [ 'json' => [
'request_id' => 'mall_' . uniqid(), 'merchant_code' => $merchantCode,
'token' => $token, 'request_date' => $requestDate,
'request_id' => $requestId,
'token' => $token,
], ],
]); ]);
$code = $res->getStatusCode(); $code = $res->getStatusCode();
@@ -505,6 +531,40 @@ class Playx extends Api
]); ]);
} }
/**
* 生成 token verify 所需签名Base64(HMAC-SHA1(canonical, key))
*/
private function buildPlayxTokenVerifySignature(string $input, string $authKey): ?string
{
$keyBytes = null;
$maybeBase64 = base64_decode($authKey, true);
if (is_string($maybeBase64) && $maybeBase64 !== '') {
$keyBytes = $maybeBase64;
}
if ($keyBytes === null) {
$isHex = ctype_xdigit($authKey) && (strlen($authKey) % 2 === 0);
if ($isHex) {
$hex = hex2bin($authKey);
if (is_string($hex) && $hex !== '') {
$keyBytes = $hex;
}
}
}
if ($keyBytes === null) {
$keyBytes = $authKey;
}
$raw = hash_hmac('sha1', $input, $keyBytes, true);
if (!is_string($raw) || $raw === '') {
return null;
}
return base64_encode($raw);
}
/** /**
* 用户资产 * 用户资产
* GET /api/v1/playx/assets?user_id=xxx * GET /api/v1/playx/assets?user_id=xxx