74 lines
2.5 KiB
PHP
74 lines
2.5 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
namespace app\api\controller\v1;
|
||
|
||
use app\api\cache\AuthTokenCache;
|
||
use app\api\controller\BaseController;
|
||
use app\api\util\ReturnCode;
|
||
use support\Request;
|
||
use support\Response;
|
||
use Tinywan\Jwt\JwtToken;
|
||
|
||
/**
|
||
* 平台鉴权接口
|
||
* 鉴权接口:/api/v1/authtoken
|
||
* GET 参数:signature, secret, time, agent_id
|
||
* 签名:signature = md5(agent_id.secret.time)
|
||
*/
|
||
class AuthTokenController extends BaseController
|
||
{
|
||
/**
|
||
* 获取 auth-token
|
||
* GET 参数:signature, secret, time, agent_id
|
||
* 返回 authtoken,后续 /api/v1/* 接口需在请求头携带 auth-token
|
||
*/
|
||
public function index(Request $request): Response
|
||
{
|
||
$agentId = trim((string) ($request->get('agent_id', '')));
|
||
$secret = trim((string) ($request->get('secret', '')));
|
||
$time = trim((string) ($request->get('time', '')));
|
||
$signature = trim((string) ($request->get('signature', '')));
|
||
|
||
if ($agentId === '' || $secret === '' || $time === '' || $signature === '') {
|
||
return $this->fail('Missing parameters: agent_id, secret, time, signature are required', ReturnCode::PARAMS_ERROR);
|
||
}
|
||
|
||
$expectedSecret = config('api.auth_token_secret', '');
|
||
if ($expectedSecret === '') {
|
||
return $this->fail('API_AUTH_TOKEN_SECRET is not configured', ReturnCode::SERVER_ERROR);
|
||
}
|
||
if ($secret !== $expectedSecret) {
|
||
return $this->fail('Invalid secret', ReturnCode::FORBIDDEN);
|
||
}
|
||
|
||
$timeVal = (int) $time;
|
||
$tolerance = (int) config('api.auth_token_time_tolerance', 300);
|
||
$now = time();
|
||
if ($timeVal < $now - $tolerance || $timeVal > $now + $tolerance) {
|
||
return $this->fail('Timestamp expired or invalid, please sync time', ReturnCode::FORBIDDEN);
|
||
}
|
||
|
||
$expectedSignature = md5($agentId . $secret . $time);
|
||
if ($signature !== $expectedSignature) {
|
||
return $this->fail('Signature verification failed', ReturnCode::FORBIDDEN);
|
||
}
|
||
|
||
$exp = (int) config('api.auth_token_exp', 86400);
|
||
$tokenResult = JwtToken::generateToken([
|
||
'id' => 0,
|
||
'agent_id' => $agentId,
|
||
'plat' => 'api_auth_token',
|
||
'access_exp' => $exp,
|
||
]);
|
||
$token = $tokenResult['access_token'];
|
||
if (!AuthTokenCache::setToken($agentId, $token)) {
|
||
return $this->fail('Failed to generate token', ReturnCode::SERVER_ERROR);
|
||
}
|
||
|
||
return $this->success([
|
||
'authtoken' => $token,
|
||
]);
|
||
}
|
||
}
|