API接口-优化/创建保存jwt

This commit is contained in:
2026-03-30 15:19:22 +08:00
parent 2d561f81b5
commit c2ce8085c2
5 changed files with 69 additions and 3 deletions

View File

@@ -24,8 +24,12 @@ PLAYX_POINTS_TO_CASH_RATIO=0.1
PLAYX_RETURN_RATIO=0.1 PLAYX_RETURN_RATIO=0.1
# 解锁比例:今日可领取上限 = yesterday_total_deposit * unlock_ratio # 解锁比例:今日可领取上限 = yesterday_total_deposit * unlock_ratio
PLAYX_UNLOCK_RATIO=0.1 PLAYX_UNLOCK_RATIO=0.1
# Daily Push 签名校验密钥(建议从部署系统注入,避免写入代码/仓库) # Daily Push 签名校验密钥(HMAC建议从部署系统注入,避免写入代码/仓库)
PLAYX_DAILY_PUSH_SECRET= PLAYX_DAILY_PUSH_SECRET=
# 合作方回调 JWT 验签密钥HS256与对端私发密钥一致与上一项可同时配置则两种均需通过
PLAYX_PARTNER_JWT_SECRET=5590a339502b133f4d0c545c3cdad159a4827dfccb3f51bb110c56f9b96568ca
# Agent authtoken/api/v1/authTokenJWT 签名密钥;留空则使用下方 buildadmin.token.key
AGENT_AUTH_JWT_SECRET=
# token 会话缓存过期时间(秒) # token 会话缓存过期时间(秒)
PLAYX_SESSION_EXPIRE_SECONDS=3600 PLAYX_SESSION_EXPIRE_SECONDS=3600
# PlayX API商城调用 PlayX 时使用) # PlayX API商城调用 PlayX 时使用)

View File

@@ -14,6 +14,7 @@ use app\common\model\MallPlayxDailyPush;
use app\common\model\MallPlayxSession; use app\common\model\MallPlayxSession;
use app\common\model\MallPlayxOrder; use app\common\model\MallPlayxOrder;
use app\common\model\MallPlayxUserAsset; use app\common\model\MallPlayxUserAsset;
use app\common\library\PlayxInboundJwt;
use support\think\Db; use support\think\Db;
use Webman\Http\Request; use Webman\Http\Request;
use support\Response; use support\Response;
@@ -156,6 +157,14 @@ class Playx extends Api
return $response; return $response;
} }
$partnerJwtSecret = strval(config('playx.partner_jwt_secret', ''));
if ($partnerJwtSecret !== '') {
$authHeader = strval($request->header('authorization', ''));
if (!PlayxInboundJwt::verifyBearer($authHeader, $partnerJwtSecret)) {
return $this->error(__('Invalid or missing JWT'), null, 0, ['statusCode' => 401]);
}
}
$body = $request->post(); $body = $request->post();
if (empty($body)) { if (empty($body)) {
$raw = $request->rawBody(); $raw = $request->rawBody();

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace app\common\library;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
/**
* PlayX / 合作方回调:校验 Authorization: Bearer JWTHS256
*/
class PlayxInboundJwt
{
public const ALG = 'HS256';
/**
* 从 Authorization 头解析 Bearer token 并校验签名与有效期
*/
public static function verifyBearer(string $authorizationHeader, string $secret): bool
{
if ($secret === '') {
return false;
}
$token = self::extractBearer($authorizationHeader);
if ($token === '') {
return false;
}
try {
JWT::decode($token, new Key($secret, self::ALG));
return true;
} catch (ExpiredException|SignatureInvalidException|\Throwable) {
return false;
}
}
public static function extractBearer(string $authorizationHeader): string
{
if (preg_match('/Bearer\s+(\S+)/i', $authorizationHeader, $m)) {
return $m[1];
}
return '';
}
}

View File

@@ -87,8 +87,8 @@ return [
'agents' => [ 'agents' => [
// 'agent_001' => 'your_secret_key', // 'agent_001' => 'your_secret_key',
], ],
// JWT 签名密钥(留空则使用 token.key // JWT 签名密钥(留空则使用 token.key;建议 AGENT_AUTH_JWT_SECRET 注入
'jwt_secret' => '', 'jwt_secret' => strval(env('AGENT_AUTH_JWT_SECRET', '')),
// 是否启用 H5 临时登录接口 /api/v1/temLogin // 是否启用 H5 临时登录接口 /api/v1/temLogin
'temp_login_enable' => true, 'temp_login_enable' => true,
// Token 有效期(秒),默认 24 小时 // Token 有效期(秒),默认 24 小时

View File

@@ -12,6 +12,11 @@ return [
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')), 'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
// Daily Push 签名校验PlayX 调用商城时使用) // Daily Push 签名校验PlayX 调用商城时使用)
'daily_push_secret' => strval(env('PLAYX_DAILY_PUSH_SECRET', '')), 'daily_push_secret' => strval(env('PLAYX_DAILY_PUSH_SECRET', '')),
/**
* 合作方 JWT 验签密钥HS256。非空时daily-push 等回调需带 Authorization: Bearer
* 仅写入部署环境变量,勿提交仓库。
*/
'partner_jwt_secret' => strval(env('PLAYX_PARTNER_JWT_SECRET', '')),
// token 会话缓存过期时间(秒) // token 会话缓存过期时间(秒)
'session_expire_seconds' => intval(env('PLAYX_SESSION_EXPIRE_SECONDS', '3600')), 'session_expire_seconds' => intval(env('PLAYX_SESSION_EXPIRE_SECONDS', '3600')),
/** /**