86 lines
2.5 KiB
PHP
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']);
|
|
}
|
|
}
|
|
|