110 lines
3.9 KiB
PHP
110 lines
3.9 KiB
PHP
<?php
|
||
|
||
namespace App\Middleware;
|
||
|
||
use app\model\User;
|
||
use Tinywan\Jwt\JwtToken;
|
||
use App\Utils\ApiResponse;
|
||
use Webman\Http\Request;
|
||
use Webman\Http\Response;
|
||
use Webman\MiddlewareInterface;
|
||
|
||
use ReflectionClass;
|
||
|
||
class JwtAuthMiddleware implements MiddlewareInterface
|
||
{
|
||
/**
|
||
* 处理请求
|
||
*
|
||
* @param Request $request
|
||
* @param callable $handler
|
||
* @return Response
|
||
*/
|
||
public function process(Request $request, callable $handler): Response
|
||
{
|
||
|
||
/**
|
||
* 通过反射获取不需要登录的方法
|
||
*/
|
||
$controller = new ReflectionClass($request->controller);
|
||
/**
|
||
* apidoc 直接继续向洋葱芯穿越
|
||
*/
|
||
if ($controller->name == 'hg\apidoc\Controller') {
|
||
return $handler($request);
|
||
}
|
||
// var_dump($controller->name);
|
||
$noNeedLogin = $controller->getDefaultProperties()['noNeedLogin'] ?? [];
|
||
if (in_array($request->action, $noNeedLogin)) {
|
||
// 不需要登录的方法继续向洋葱芯穿越
|
||
return $handler($request);
|
||
}
|
||
|
||
// 获取 Authorization 头部中的 token,通常格式为 "Bearer <token>"
|
||
$token1 = $request->header('Authorization');
|
||
$token2 = $request->header('Token');
|
||
$token_tmp = !empty($token1) ? $token1 : $token2;
|
||
|
||
if (strpos($token_tmp, "Bearer ") === false) {
|
||
$token = 'Bearer ' . $token_tmp;
|
||
} else {
|
||
$token = $token_tmp;
|
||
}
|
||
// 检查 token 是否为空
|
||
if (empty($token)) {
|
||
// return ApiResponse::error(401, ['error' => '缺少令牌'], '未授权');
|
||
return response('', 401, ['error' => '缺少令牌']);
|
||
}
|
||
// var_dump($token);
|
||
|
||
// 移除 Bearer 前缀并获取纯 token
|
||
// if (strpos($token, 'Bearer ') === 0) {
|
||
// $token = substr($token, 7); // 去掉 "Bearer " 部分
|
||
// }
|
||
|
||
try {
|
||
// 解码 token,返回用户信息
|
||
$decoded = JwtToken::getExtend($token);
|
||
if (!empty($decoded['user_type'])) {
|
||
$user_type = $decoded['user_type'];
|
||
// 权限校验
|
||
switch ($user_type) {
|
||
case 'user':
|
||
// 如果是普通用户,禁止访问 admin 或 generalization 控制器
|
||
if (false !== strstr($controller->name, 'admin') || false !== strstr($controller->name, 'generalization')) {
|
||
return response('', 401, ['error' => '无权限']);
|
||
}
|
||
break;
|
||
|
||
case 'generalization':
|
||
// 如果是推广员,禁止访问 admin 控制器
|
||
if (false !== strstr($controller->name, 'admin')) {
|
||
return response('', 401, ['error' => '无权限']);
|
||
}
|
||
break;
|
||
|
||
case 'admin':
|
||
// 如果是管理员,不做限制(可以访问所有控制器)
|
||
break;
|
||
|
||
default:
|
||
// 其他类型的用户,如果有的话
|
||
return response('', 401, ['error' => '未知的用户类型']);
|
||
}
|
||
}
|
||
|
||
} catch (\Exception $e) {
|
||
// var_dump($e);
|
||
// 解码失败,返回无效令牌错误
|
||
// return ApiResponse::error(401, ['error' => '无效的令牌'], '无效的令牌');
|
||
return response('', 401, ['error' => '无效的令牌']);
|
||
}
|
||
|
||
// 将解码后的用户信息存储到请求对象的 user 属性中
|
||
// $request = $request->withAttribute('user', $decoded);
|
||
$request->data = $decoded;
|
||
// 继续处理请求,传递给下一个中间件或控制器,并返回响应
|
||
return $handler($request);
|
||
}
|
||
}
|