Files
docs/thinkphp/app/middleware/Auth.php
cenzuhai 3a04eede84 feat: 初始化进销存数据开放平台项目
初始化完整的前后端项目结构,包含ThinkPHP后端API服务和Next.js前端管理系统,添加基础配置、中间件、模型、路由等核心代码,以及项目文档和静态资源。
2026-07-08 17:48:00 +08:00

92 lines
2.6 KiB
PHP
Raw Permalink 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
namespace app\middleware;
use app\model\ApiKey;
use app\model\Client;
use app\model\Permission;
use app\service\Signature;
use think\Request;
use think\Response;
/**
* API鉴权中间件
*/
class Auth
{
/**
* 处理请求
*/
public function handle(Request $request, \Closure $next)
{
// 1. 提取必要Headers
$apiKey = $request->header('X-API-Key');
$timestamp = $request->header('X-Timestamp');
$sign = $request->header('X-Sign');
if (empty($apiKey) || empty($timestamp) || empty($sign)) {
return json([
'code' => 401,
'msg' => '缺少鉴权头: 需要 X-API-Key, X-Timestamp, X-Sign'
], 401);
}
// 2. 查询API Key连带查询client和permission
$apiKeyObj = ApiKey::with(['client', 'permission'])
->where('api_key', $apiKey)
->find();
if (!$apiKeyObj) {
return json([
'code' => 401,
'msg' => '无效的 API Key'
], 401);
}
// 3. 检查状态
if ($apiKeyObj->status != ApiKey::STATUS_ENABLED) {
return json([
'code' => 403,
'msg' => 'API Key 已被禁用'
], 403);
}
$clientObj = $apiKeyObj->client;
if (!$clientObj || $clientObj->status != Client::STATUS_ENABLED) {
return json([
'code' => 403,
'msg' => '客户账号已被停用API 访问被拒绝'
], 403);
}
// 4. 验证签名
$params = $request->param();
if (!Signature::verify($params, $timestamp, $sign, $apiKeyObj->api_secret_hash)) {
return json([
'code' => 401,
'msg' => '签名验证失败'
], 401);
}
// 5. 检查权限配置
$permission = Permission::where('api_key_id', $apiKeyObj->id)->find();
if (!$permission) {
return json([
'code' => 403,
'msg' => '未配置 API 权限,请联系管理员'
], 403);
}
// 6. 将鉴权上下文存入请求
$request->authContext = [
'api_key_id' => $apiKeyObj->id,
'api_key' => $apiKeyObj->api_key,
'client_id' => $clientObj->id,
'client_name' => $clientObj->name,
'permission' => $permission,
'rate_limit_per_minute' => $apiKeyObj->rate_limit_per_minute,
'rate_limit_per_day' => $apiKeyObj->rate_limit_per_day,
];
return $next($request);
}
}