数据库备份
This commit is contained in:
@@ -17,7 +17,7 @@ class Admin extends Backend
|
||||
{
|
||||
protected ?object $model = null;
|
||||
|
||||
protected array|string $preExcludeFields = ['create_time', 'update_time', 'password', 'salt', 'login_failure', 'last_login_time', 'last_login_ip', 'agent_id', 'agent_api_secret', 'channel_id'];
|
||||
protected array|string $preExcludeFields = ['create_time', 'update_time', 'password', 'salt', 'login_failure', 'last_login_time', 'last_login_ip', 'channel_id'];
|
||||
|
||||
protected array|string $quickSearchField = ['username', 'nickname'];
|
||||
|
||||
@@ -98,15 +98,6 @@ class Admin extends Backend
|
||||
$this->model->startTrans();
|
||||
try {
|
||||
$result = $this->model->save($data);
|
||||
if ($result !== false) {
|
||||
$agentId = strtolower(md5($this->model->username . $this->model->id));
|
||||
$agentSecret = strtoupper(md5($this->model->username . $this->model->id));
|
||||
// 使用原生 SQL,避免 ThinkORM 按当前表结构校验字段时因未迁移缺少 agent_api_secret 列而报错
|
||||
Db::execute(
|
||||
'UPDATE `admin` SET `agent_id` = ?, `agent_api_secret` = ? WHERE `id` = ?',
|
||||
[$agentId, $agentSecret, $this->model->id]
|
||||
);
|
||||
}
|
||||
if (!empty($data['group_arr'])) {
|
||||
$groupAccess = [];
|
||||
foreach ($data['group_arr'] as $datum) {
|
||||
|
||||
@@ -13,7 +13,7 @@ class AdminInfo extends Backend
|
||||
{
|
||||
protected ?object $model = null;
|
||||
|
||||
protected array|string $preExcludeFields = ['username', 'last_login_time', 'password', 'salt', 'status', 'channel_id', 'agent_id', 'agent_api_secret'];
|
||||
protected array|string $preExcludeFields = ['username', 'last_login_time', 'password', 'salt', 'status', 'channel_id'];
|
||||
protected array $authAllowFields = ['id', 'username', 'nickname', 'avatar', 'email', 'mobile', 'motto', 'last_login_time'];
|
||||
|
||||
protected function initController(Request $request): ?Response
|
||||
|
||||
@@ -97,7 +97,7 @@ return [
|
||||
'Group Name Arr' => 'Group Name Arr',
|
||||
'Push succeeded' => 'Push succeeded',
|
||||
'Manual push failed' => 'Manual push failed',
|
||||
'PlayX API not configured' => 'PlayX API not configured',
|
||||
'playX API not configured' => 'playX API not configured',
|
||||
'Current grant status cannot be manually pushed' => 'Current grant status cannot be manually pushed',
|
||||
'Order status must be PENDING' => 'Order status must be PENDING',
|
||||
'Missing required fields' => 'Missing required fields',
|
||||
@@ -107,4 +107,6 @@ return [
|
||||
'Shipped successfully' => 'Shipped successfully',
|
||||
'Approved successfully' => 'Approved successfully',
|
||||
'Rejected successfully' => 'Rejected successfully',
|
||||
'Success' => 'success',
|
||||
'Failed' => 'failed',
|
||||
];
|
||||
@@ -116,7 +116,7 @@ return [
|
||||
'Group Name Arr' => '分组名称数组',
|
||||
'Push succeeded' => '推送成功',
|
||||
'Manual push failed' => '手动推送失败',
|
||||
'PlayX API not configured' => 'PlayX 接口未配置',
|
||||
'playX API not configured' => 'playX 接口未配置',
|
||||
'Current grant status cannot be manually pushed' => '当前发放状态不可手动推送',
|
||||
'Order status must be PENDING' => '订单状态须为处理中',
|
||||
'Missing required fields' => '缺少必填项',
|
||||
@@ -126,4 +126,6 @@ return [
|
||||
'Shipped successfully' => '发货成功',
|
||||
'Approved successfully' => '审核通过',
|
||||
'Rejected successfully' => '驳回成功',
|
||||
'Success' => '成功',
|
||||
'Failed' => '失败',
|
||||
];
|
||||
@@ -21,8 +21,6 @@ use support\think\Db;
|
||||
* @property string $password 密码密文
|
||||
* @property string $salt 密码盐
|
||||
* @property string $status 状态:enable=启用,disable=禁用
|
||||
* @property string $agent_id 代理 ID(API 鉴权)
|
||||
* @property string $agent_api_secret Agent API 密钥
|
||||
*/
|
||||
class Admin extends Model
|
||||
{
|
||||
|
||||
@@ -9,9 +9,7 @@ use Throwable;
|
||||
use app\common\controller\Api;
|
||||
use app\common\facade\Token;
|
||||
use app\common\library\Auth as UserAuth;
|
||||
use app\common\library\AgentJwt;
|
||||
use app\common\model\MallUserAsset;
|
||||
use app\admin\model\Admin;
|
||||
use Webman\Http\Request;
|
||||
use support\Response;
|
||||
|
||||
@@ -20,83 +18,12 @@ use support\Response;
|
||||
*/
|
||||
class Auth extends Api
|
||||
{
|
||||
/**
|
||||
* Agent Token 类型
|
||||
*/
|
||||
public const TOKEN_TYPE = 'agent';
|
||||
|
||||
/**
|
||||
* 时间戳有效范围(秒),防止重放攻击
|
||||
*/
|
||||
protected int $timeTolerance = 300;
|
||||
|
||||
/**
|
||||
* 临时登录 token 有效期(秒)
|
||||
*/
|
||||
protected int $tempTokenExpire = 86400;
|
||||
|
||||
/**
|
||||
* 获取鉴权 Token(GET 请求)
|
||||
* 参数仅从 Query 读取:signature、secret、agent_id、time
|
||||
* 返回:authtoken;失败返回 code=0 及失败信息
|
||||
*/
|
||||
public function authToken(Request $request): Response
|
||||
{
|
||||
$response = $this->initializeApi($request);
|
||||
if ($response !== null) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$signature = $request->get('signature', '');
|
||||
$secret = $request->get('secret', '');
|
||||
$agentId = $request->get('agent_id', '');
|
||||
$time = $request->get('time', '');
|
||||
|
||||
if ($signature === '' || $secret === '' || $agentId === '' || $time === '') {
|
||||
return $this->error(__('Parameter signature/secret/agent_id/time can not be empty'));
|
||||
}
|
||||
|
||||
$timestamp = intval($time);
|
||||
if ($timestamp <= 0) {
|
||||
return $this->error(__('Invalid timestamp'));
|
||||
}
|
||||
|
||||
$now = time();
|
||||
if ($timestamp < $now - $this->timeTolerance || $timestamp > $now + $this->timeTolerance) {
|
||||
return $this->error(__('Timestamp expired'));
|
||||
}
|
||||
|
||||
$admin = Admin::where('agent_id', $agentId)->find();
|
||||
if (!$admin) {
|
||||
return $this->error(__('Agent not found'));
|
||||
}
|
||||
|
||||
$apiSecret = strval($admin->agent_api_secret ?? '');
|
||||
if ($apiSecret === '') {
|
||||
return $this->error(__('Agent not found'));
|
||||
}
|
||||
|
||||
if ($apiSecret !== $secret) {
|
||||
return $this->error(__('Invalid agent or secret'));
|
||||
}
|
||||
|
||||
$expectedSignature = strtoupper(md5($agentId . $secret . $time));
|
||||
if (!hash_equals($expectedSignature, $signature)) {
|
||||
return $this->error(__('Invalid signature'));
|
||||
}
|
||||
|
||||
$expire = intval(config('buildadmin.agent_auth.token_expire', 86400));
|
||||
$payload = [
|
||||
'agent_id' => $agentId,
|
||||
'admin_id' => $admin->id,
|
||||
];
|
||||
$authtoken = AgentJwt::encode($payload, $expire);
|
||||
|
||||
return $this->success('', [
|
||||
'authtoken' => $authtoken,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* H5 临时登录(GET/POST)
|
||||
* 参数:username
|
||||
@@ -109,7 +36,7 @@ class Auth extends Api
|
||||
return $response;
|
||||
}
|
||||
|
||||
$enabled = config('buildadmin.agent_auth.temp_login_enable', false);
|
||||
$enabled = config('buildadmin.temp_login.enable', false);
|
||||
if (!$enabled) {
|
||||
return $this->error(__('Temp login is disabled'));
|
||||
}
|
||||
@@ -145,7 +72,7 @@ class Auth extends Api
|
||||
|
||||
$token = Random::uuid();
|
||||
$refreshToken = Random::uuid();
|
||||
$expire = config('buildadmin.agent_auth.temp_login_expire', $this->tempTokenExpire);
|
||||
$expire = config('buildadmin.temp_login.expire', $this->tempTokenExpire);
|
||||
$assetId = intval($asset->getKey());
|
||||
Token::set($token, UserAuth::TOKEN_TYPE_MALL_USER, $assetId, $expire);
|
||||
Token::set($refreshToken, UserAuth::TOKEN_TYPE_MALL_USER . '-refresh', $assetId, 2592000);
|
||||
|
||||
@@ -43,7 +43,6 @@ return [
|
||||
'You have no permission' => 'No permission!',
|
||||
'Parameter error' => 'Parameter error!',
|
||||
'Parameter %s can not be empty' => 'Parameter %s cannot be empty',
|
||||
'Parameter signature/secret/agent_id/time can not be empty' => 'Parameter signature/secret/agent_id/time cannot be empty',
|
||||
'Invalid timestamp' => 'Invalid timestamp',
|
||||
'Timestamp expired' => 'Timestamp expired',
|
||||
'Invalid agent or secret' => 'Invalid agent or secret',
|
||||
|
||||
@@ -35,16 +35,15 @@ return [
|
||||
'Account not exist' => 'Akaun tidak wujud',
|
||||
'Account disabled' => 'Akaun dilumpuhkan',
|
||||
'Token login failed' => 'Log masuk token gagal',
|
||||
'Please try again after 1 day' => 'Percubaan gagal terlalu kerap, sila cuba semula selepas 1 hari',
|
||||
'Please try again after 1 day' => 'Percubaan gagal terlalu kerap, sila cuba semula selepas 24 jam',
|
||||
'Password is incorrect' => 'Kata laluan tidak betul',
|
||||
'You are not logged in' => 'Anda belum log masuk',
|
||||
'Unknown operation' => 'Operasi tidak diketahui',
|
||||
'No action available, please contact the administrator~' => 'Tiada tindakan tersedia, sila hubungi pentadbir~',
|
||||
'No action available, please contact the administrator~' => 'Tiada tindakan tersedia, sila hubungi pentadbir.',
|
||||
'Please login first' => 'Sila log masuk dahulu!',
|
||||
'You have no permission' => 'Tiada kebenaran!',
|
||||
'Parameter error' => 'Ralat parameter!',
|
||||
'Parameter %s can not be empty' => 'Parameter %s tidak boleh kosong',
|
||||
'Parameter signature/secret/agent_id/time can not be empty' => 'Parameter signature/secret/agent_id/time tidak boleh kosong',
|
||||
'Invalid timestamp' => 'Cap masa tidak sah',
|
||||
'Timestamp expired' => 'Cap masa tamat tempoh',
|
||||
'Invalid agent or secret' => 'Ejen atau rahsia tidak sah',
|
||||
|
||||
@@ -43,7 +43,6 @@ return [
|
||||
'You have no permission' => '没有权限操作!',
|
||||
'Parameter error' => '参数错误!',
|
||||
'Parameter %s can not be empty' => '参数%s不能为空',
|
||||
'Parameter signature/secret/agent_id/time can not be empty' => '参数 signature/secret/agent_id/time 不能为空',
|
||||
'Invalid timestamp' => '无效的时间戳',
|
||||
'Timestamp expired' => '时间戳已过期',
|
||||
'Invalid agent or secret' => '代理或密钥无效',
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Agent 鉴权 JWT 工具
|
||||
*/
|
||||
class AgentJwt
|
||||
{
|
||||
public const ALG = 'HS256';
|
||||
|
||||
/**
|
||||
* 生成 JWT authtoken
|
||||
* @param array $payload agent_id、admin_id 等
|
||||
* @param int $expire 有效期(秒)
|
||||
*/
|
||||
public static function encode(array $payload, int $expire = 86400): string
|
||||
{
|
||||
$now = time();
|
||||
$payload['iat'] = $now;
|
||||
$payload['exp'] = $now + $expire;
|
||||
$secret = self::getSecret();
|
||||
return JWT::encode($payload, $secret, self::ALG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析并验证 JWT,返回 payload
|
||||
* @return array payload,失败返回空数组
|
||||
*/
|
||||
public static function decode(string $token): array
|
||||
{
|
||||
if ($token === '') {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
$secret = self::getSecret();
|
||||
$decoded = JWT::decode($token, new Key($secret, self::ALG));
|
||||
return (array) $decoded;
|
||||
} catch (ExpiredException|SignatureInvalidException|\Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 JWT 是否有效
|
||||
*/
|
||||
public static function verify(string $token): bool
|
||||
{
|
||||
return !empty(self::decode($token));
|
||||
}
|
||||
|
||||
private static function getSecret(): string
|
||||
{
|
||||
$secret = config('buildadmin.agent_auth.jwt_secret', '');
|
||||
if ($secret === '') {
|
||||
$secret = config('buildadmin.token.key', '');
|
||||
}
|
||||
return $secret;
|
||||
}
|
||||
}
|
||||
@@ -165,18 +165,6 @@ if (!function_exists('get_auth_token')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_agent_jwt_payload')) {
|
||||
/**
|
||||
* 解析 Agent JWT authtoken,返回 payload(agent_id、admin_id 等)
|
||||
* @param string $token authtoken
|
||||
* @return array 成功返回 payload,失败返回空数组
|
||||
*/
|
||||
function get_agent_jwt_payload(string $token): array
|
||||
{
|
||||
return \app\common\library\AgentJwt::decode($token);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_controller_path')) {
|
||||
/**
|
||||
* 从 Request 或路由获取控制器路径(等价于 ThinkPHP controllerPath)
|
||||
|
||||
@@ -76,6 +76,13 @@ abstract class BaseController
|
||||
*/
|
||||
protected function result(string $msg, mixed $data = null, int $code = 0, array $header = []): Response
|
||||
{
|
||||
if (trim($msg) === '') {
|
||||
$msg = $code === 1 ? __('Success') : __('Failed');
|
||||
if (trim($msg) === '') {
|
||||
$msg = $code === 1 ? 'success' : 'failed';
|
||||
}
|
||||
}
|
||||
|
||||
$body = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
|
||||
Reference in New Issue
Block a user