Files
dafuweng-saiadmin6.x/server/app/api/middleware/CheckApiAuthMiddleware.php

75 lines
2.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\api\middleware;
use support\Log;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
use Tinywan\Jwt\JwtToken;
use Tinywan\Jwt\Exception\JwtTokenException;
use Tinywan\Jwt\Exception\JwtTokenExpiredException;
use plugin\saiadmin\exception\ApiException;
/**
* API 鉴权中间件
* 校验请求头 auth-token或 Authorization: Bearer xxx白名单路径不校验
*/
class CheckApiAuthMiddleware implements MiddlewareInterface
{
/** 不需要 auth-token 的路径(仅获取 token 的接口) */
private const WHITELIST = [
'api/authToken',
];
public function process(Request $request, callable $handler): Response
{
$path = trim($request->path(), '/');
if ($this->isWhitelist($path)) {
return $handler($request);
}
$token = $request->header('auth-token');
if (empty($token)) {
$auth = $request->header('authorization');
if ($auth && stripos($auth, 'Bearer ') === 0) {
$token = trim(substr($auth, 7));
}
}
if (empty($token)) {
throw new ApiException('缺少 auth-token请先调用 /api/authToken 获取', 401);
}
try {
// ACCESS_TOKEN = 1JwtToken 内部私有常量)
$decoded = JwtToken::verify(1, $token);
$extend = $decoded['extend'] ?? [];
if (($extend['plat'] ?? '') !== 'api') {
throw new ApiException('auth-token 无效', 401);
}
} catch (JwtTokenExpiredException $e) {
Log::error('code=401, auth-token 已过期,请重新获取, 报错信息'. $e);
throw new ApiException('auth-token 已过期,请重新获取', 401);
} catch (JwtTokenException $e) {
Log::error('code=401, message=auth-token 无效, 报错信息'. $e);
throw new ApiException($e->getMessage() ?: 'auth-token 无效', 401);
} catch (\Throwable $e) {
Log::error('code=401, message=auth-token 校验失败, 报错信息'. $e);
throw new ApiException('auth-token 校验失败', 401);
}
return $handler($request);
}
private function isWhitelist(string $path): bool
{
foreach (self::WHITELIST as $prefix) {
if ($path === $prefix || str_starts_with($path, $prefix . '/')) {
return true;
}
}
return false;
}
}