1.重新设置Token验证接口
This commit is contained in:
@@ -34,7 +34,7 @@ AGENT_AUTH_JWT_SECRET=
|
||||
PLAYX_SESSION_EXPIRE_SECONDS=3600
|
||||
# verifyToken 是否仅本地联调(false=走对方远程校验)
|
||||
PLAYX_VERIFY_TOKEN_LOCAL_ONLY=false
|
||||
# verifyToken:填完整 https URL 时仅发 request_id+token;填相对路径时拼 PLAYX_ANGPOW_IMPORT_BASE_URL 并发商户签名体
|
||||
# verifyToken:完整 https URL 时 X-Request-Signature 与 angpow-imports 同源,Body 含 merchant_code/report_date/request_id/token;相对路径时拼基址且 Body 用 request_date
|
||||
PLAYX_TOKEN_VERIFY_URL=https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token
|
||||
# verifyToken 仅本地联调时的默认用户ID
|
||||
PLAYX_VERIFY_TOKEN_LOCAL_DEFAULT_USER_ID=testmyr
|
||||
|
||||
@@ -443,12 +443,32 @@ class Playx extends Api
|
||||
$client = new \GuzzleHttp\Client($clientOptions);
|
||||
|
||||
if ($isAbsoluteVerifyUrl) {
|
||||
$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'));
|
||||
}
|
||||
|
||||
// 与 angpow-imports 一致:HMAC-SHA1 → Base64;密钥 hex/base64 兼容;仅 X-Request-Signature 头
|
||||
$reportDate = strval(time());
|
||||
$signatureInput = 'merchant_code=' . $merchantCode
|
||||
. '&report_date=' . $reportDate
|
||||
. '&request_id=' . $requestId
|
||||
. '&token=' . $token;
|
||||
$signature = $this->buildPlayxTokenVerifySignature($signatureInput, $authKey);
|
||||
if ($signature === null) {
|
||||
return $this->error(__('Invalid signature'), null, 0, ['statusCode' => 500]);
|
||||
}
|
||||
|
||||
$headers = [
|
||||
'Content-Type' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'X-Request-Signature' => $signature,
|
||||
];
|
||||
$payload = [
|
||||
'request_id' => $requestId,
|
||||
'token' => $token,
|
||||
'merchant_code' => $merchantCode,
|
||||
'report_date' => $reportDate,
|
||||
'request_id' => $requestId,
|
||||
'token' => $token,
|
||||
];
|
||||
$res = $client->post($targetVerifyUrl, [
|
||||
'headers' => $headers,
|
||||
|
||||
@@ -32,7 +32,7 @@ return [
|
||||
'api' => [
|
||||
'base_url' => strval(env('PLAYX_API_BASE_URL', '')),
|
||||
'secret_key' => strval(env('PLAYX_API_SECRET_KEY', '')),
|
||||
// 完整 https URL:回调校验,Body 仅 request_id + token;相对路径:拼 angpow_import.base_url + 商户签名字段
|
||||
// 完整 https URL:回调校验,X-Request-Signature 与 angpow-imports 同源;相对路径:拼 angpow_import.base_url + request_date 商户体
|
||||
'token_verify_url' => strval(env('PLAYX_TOKEN_VERIFY_URL', '/api/v1/auth/verify-token')),
|
||||
'bonus_grant_url' => '/api/v1/bonus/grant',
|
||||
'balance_credit_url' => '/api/v1/balance/credit',
|
||||
|
||||
@@ -73,16 +73,16 @@ flowchart LR
|
||||
2. playX 前端通过 postMessage 将 **playX 下发的 token**(及必要上下文)传给商城 H5。
|
||||
3. 商城 H5 调用商城后端 **`POST /api/v1/mall/verifyToken`**(前端只传 `token`),由商城后端向 **Token Verification API** 发起校验。
|
||||
4. **前提**:配置 **`playX.verify_token_local_only = false`**,且 **`PLAYX_TOKEN_VERIFY_URL`** 已配置:
|
||||
- **完整 `https://...` URL**(如回调:`https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token`):商城对该地址 `POST`,Body 仅 **`request_id` + `token`**,无需 `PLAYX_ANGPOW_IMPORT_BASE_URL`。
|
||||
- **相对路径**(如 `/api/v1/auth/verify-token`):需同时配置 **`PLAYX_ANGPOW_IMPORT_BASE_URL`**,并按商户约定附带 **`merchant_code` / `request_date` / `X-Request-Signature`** 等。
|
||||
- **完整 `https://...` URL**(如回调):商城 `POST` 该地址;**`X-Request-Signature` 生成方式与 `PLAYX_ANGPOW_IMPORT_PATH`(angpow-imports)一致**;Body 含 **`merchant_code`、`report_date`、`request_id`、`token`**;需配置 **`PLAYX_ANGPOW_MERCHANT_CODE`**、**`PLAYX_ANGPOW_IMPORT_AUTH_KEY`**;无需 `PLAYX_ANGPOW_IMPORT_BASE_URL`。
|
||||
- **相对路径**(如 `/api/v1/auth/verify-token`):需同时配置 **`PLAYX_ANGPOW_IMPORT_BASE_URL`**,Body 使用 **`request_date`**,并按商户约定附带签名等。
|
||||
5. playX 返回 **`user_id`、`username`**(及可选会话过期时间等)。
|
||||
6. 商城写入 **`mall_playx_session`**(`session_id` + 上述 `user_id`/`username` + 过期时间),后续 H5 可用 **`session_id`** 或 **`token`(商城临时 token,见模式 B)** 调用资产/领取等接口。
|
||||
|
||||
幂等与安全:
|
||||
|
||||
- H5 **不要**把 playX 的 `user_id` 当作唯一可信凭据直传下单;**以 token 换 session** 或由商城签发 token 的流程为准。
|
||||
- 若 `PLAYX_TOKEN_VERIFY_URL` 为**完整 https URL**:对端按回调文档校验,商城后端只组 **`request_id` + `token`**,H5 不参与。
|
||||
- 若为**相对路径 + 基地址**商户网关:鉴权/签名由商城后端完成(`merchant_code/request_date/request_id` + `X-Request-Signature`);H5 不参与签名计算。
|
||||
- 若 `PLAYX_TOKEN_VERIFY_URL` 为**完整 https URL**:`X-Request-Signature` 与 angpow-imports 同源算法;Body 含 **`merchant_code`、`report_date`、`request_id`、`token`**;H5 不参与签名。
|
||||
- 若为**相对路径 + 基地址**商户网关:鉴权/签名由商城后端完成(`merchant_code/request_date/request_id` + `X-Request-Signature` 等);H5 不参与签名计算。
|
||||
|
||||
#### 4.1.3 模式 B:本地 / 无 playX 环境(商城自校验,不请求 playX)
|
||||
|
||||
@@ -222,10 +222,14 @@ flowchart LR
|
||||
|
||||
- **完整 URL**:由环境变量 **`PLAYX_TOKEN_VERIFY_URL`** 填完整地址,例如:
|
||||
`https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token`
|
||||
- **请求 Header**:与 **`PLAYX_ANGPOW_IMPORT_PATH`(angpow-imports)** 相同,仅 **`Content-Type: application/json`**、**`X-Request-Signature`**(`Base64(HMAC-SHA1(canonical, PLAYX_ANGPOW_IMPORT_AUTH_KEY))`,密钥解析规则与 angpow 一致:支持 hex / base64 / 明文)。
|
||||
- **签名明文 canonical**:`merchant_code={merchant_code}&report_date={report_date}&request_id={request_id}&token={token}`(`report_date` 为 Unix 秒时间戳字符串,与 angpow 字段命名一致)。
|
||||
- **请求 Body**:
|
||||
|
||||
| 字段名 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `merchant_code` | String | 是 | 与 `PLAYX_ANGPOW_MERCHANT_CODE` 一致。 |
|
||||
| `report_date` | String | 是 | 与参与签名的 `report_date` 一致(秒级时间戳字符串)。 |
|
||||
| `request_id` | String | 是 | 商城生成的请求追踪号。 |
|
||||
| `token` | String | 是 | 前端传入的 playX 临时凭证。 |
|
||||
|
||||
@@ -233,6 +237,8 @@ flowchart LR
|
||||
|
||||
```json
|
||||
{
|
||||
"merchant_code": "plx",
|
||||
"report_date": "1700000000",
|
||||
"request_id": "mall_20260319_9f1b6d",
|
||||
"token": "eyJhbGciOi..."
|
||||
}
|
||||
|
||||
@@ -300,8 +300,8 @@ curl -X POST 'https://{商城域名}/api/v1/mall/dailyPush' \
|
||||
**前端入参约定(重要)**:
|
||||
- 前端/客户端调用本接口时,**只需要传 `token`**(或兼容传 `session`)。
|
||||
- 商城后端调用 playX 校验时:
|
||||
- 若 **`PLAYX_TOKEN_VERIFY_URL` 为完整 `https://` URL**(回调网关):后端只向对方发送 **`request_id` + `token`**(与对端文档一致),无需前端传商户字段。
|
||||
- 若为**相对路径**:后端会拼 **`PLAYX_ANGPOW_IMPORT_BASE_URL`**,并生成 **`merchant_code` / `request_date` / `request_id` / `X-Request-Signature`**,前端仍不参与签名。
|
||||
- 若 **`PLAYX_TOKEN_VERIFY_URL` 为完整 `https://` URL**(回调网关):**`X-Request-Signature` 生成方式与 angpow-imports(`PLAYX_ANGPOW_IMPORT_PATH`)一致**(`HMAC-SHA1` → `Base64`,密钥 `PLAYX_ANGPOW_IMPORT_AUTH_KEY`);Body 含 **`merchant_code`、`report_date`、`request_id`、`token`**;canonical 为 `merchant_code=...&report_date=...&request_id=...&token=...`。
|
||||
- 若为**相对路径**:后端会拼 **`PLAYX_ANGPOW_IMPORT_BASE_URL`**,Body 使用 **`request_date`**,并生成 **`merchant_code` / `request_date` / `request_id` / `X-Request-Signature`** 等,前端仍不参与签名。
|
||||
- 若仅传 `token` 仍校验失败,多为 token 无效/过期或上游 URL 未放通,并非前端少传字段。
|
||||
|
||||
**请求示例:**
|
||||
@@ -633,9 +633,9 @@ GET /api/v1/mall/addressList?session_id=fc7f3e3f0d0f4cb29f66e4c8fbab4f66
|
||||
| `PLAYX_DAILY_PUSH_SECRET` | 非空则 Daily Push 必须带合法 HMAC 头 |
|
||||
| `PLAYX_VERIFY_TOKEN_LOCAL_ONLY` | 为 true 时 verifyToken 不请求 playX 远程 |
|
||||
| `PLAYX_ANGPOW_IMPORT_BASE_URL` | Angpow 推送等接口基地址;**相对路径** `verify-token` 时亦作其基地址 |
|
||||
| `PLAYX_TOKEN_VERIFY_URL` | **完整 `https://` URL**:回调校验,Body 仅 `request_id`+`token`;**相对路径**:拼基地址 + 商户签名体 |
|
||||
| `PLAYX_ANGPOW_MERCHANT_CODE` | 仅相对路径 `verify-token` 时使用 |
|
||||
| `PLAYX_ANGPOW_IMPORT_AUTH_KEY` | 仅相对路径 `verify-token` 时 HMAC 密钥 |
|
||||
| `PLAYX_TOKEN_VERIFY_URL` | **完整 `https://` URL**:回调校验,签名与 angpow-imports 同源;**相对路径**:拼基地址 + `request_date` 商户体 |
|
||||
| `PLAYX_ANGPOW_MERCHANT_CODE` | 回调与相对路径 `verify-token` 均需 |
|
||||
| `PLAYX_ANGPOW_IMPORT_AUTH_KEY` | 回调与相对路径 `verify-token` 的 HMAC 密钥(与 angpow-imports 相同) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user