Files
webman-buildadmin/app/api/controller/V1.php
2026-04-16 17:38:21 +08:00

86 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace app\api\controller;
use app\common\controller\Api;
use app\common\facade\Token;
use ba\Random;
use Webman\Http\Request;
use support\Response;
use function response;
class V1 extends Api
{
public function authToken(Request $request): Response
{
$responseInit = $this->initializeApi($request);
if ($responseInit !== null) {
return $responseInit;
}
$secret = trim((string) $request->get('secret', ''));
$timestampRaw = $request->get('timestamp', '');
$deviceId = trim((string) $request->get('device_id', ''));
$signature = trim((string) $request->get('signature', ''));
if ($secret === '' || $timestampRaw === '' || $deviceId === '' || $signature === '') {
return $this->mobileResult(1001, 'Missing parameters');
}
$serverSecret = (string) env('AUTH_TOKEN_SECRET', '');
if ($serverSecret === '' || !hash_equals($serverSecret, $secret)) {
return $this->mobileResult(1103, 'Invalid secret');
}
$timestamp = filter_var($timestampRaw, FILTER_VALIDATE_INT);
if ($timestamp === false) {
return $this->mobileResult(1002, 'Invalid parameter format');
}
$now = time();
$skew = abs($now - $timestamp);
if ($skew > 300) {
return $this->mobileResult(3001, 'Invalid timestamp');
}
$params = [
'device_id' => $deviceId,
'secret' => $secret,
'timestamp' => (string) $timestamp,
];
ksort($params);
$pairs = [];
foreach ($params as $k => $v) {
$pairs[] = $k . '=' . $v;
}
$plain = implode('&', $pairs);
$expected = strtoupper(md5($plain));
if (!hash_equals($expected, $signature)) {
return $this->mobileResult(1103, 'Invalid signature');
}
$token = Random::uuid();
$expire = 60 * 60 * 24;
Token::set($token, 'auth-token', 0, $expire);
return $this->mobileResult(1, 'ok', [
'auth_token' => $token,
'expires_in' => $expire,
'server_time' => $now,
]);
}
private function mobileResult(int $code, string $message, array $data = []): Response
{
$payload = [
'code' => $code,
'message' => __($message),
'data' => $data,
];
return response(json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 200, ['Content-Type' => 'application/json']);
}
}