ThinkPHP6中间件与权限控制
中间件是现代Web框架中非常重要的概念,它可以在请求到达控制器之前或之后执行特定逻辑,非常适合处理认证、权限验证、日志记录、CORS等横切关注点。ThinkPHP6的中间件系统设计优雅且灵活,本文将详细介绍其使用方法和权限控制的实战方案。
一、中间件基础
// 创建中间件
namespace app\middleware;
class Auth {
public function handle($request, \Closure $next) {
// 前置中间件:在控制器执行前运行
if (!session('user_id')) {
return redirect('/login');
}
$response = $next($request);
// 后置中间件:在控制器执行后运行
return $response;
}
}
// 带参数的中间件
class CheckRole {
public function handle($request, \Closure $next, string $role) {
$user = getCurrentUser();
if ($user->role !== $role) {
throw new \HttpException(403, '无权访问');
}
return $next($request);
}
}
二、中间件注册
// 全局中间件 - 在middleware.php中
return [
\app\middleware\CORS::class,
\app\middleware\RequestLog::class,
];
// 路由中间件
use think\facade\Route;
Route::group(function() {
Route::get('user/profile', 'User/profile');
Route::post('user/update', 'User/update');
})->middleware(\app\middleware\Auth::class);
// 带参数的路由中间件
Route::get('admin/dashboard', 'Admin/dashboard')
->middleware(\app\middleware\CheckRole::class, 'admin');
三、RBAC权限控制实现
// 权限检查中间件
class PermissionCheck {
public function handle($request, \Closure $next) {
$userId = session('user_id');
$controller = $request->controller();
$action = $request->action();
// 超级管理员跳过检查
if ($this->isSuperAdmin($userId)) {
return $next($request);
}
// 检查权限
if (!$this->checkPermission($userId, $controller, $action)) {
if ($request->isAjax()) {
return json(['code' => 0, 'msg' => '无权操作']);
}
return redirect('/403');
}
return $next($request);
}
private function checkPermission($userId, $controller, $action) {
$user = \app\model\User::find($userId);
$roles = $user->roles;
foreach ($roles as $role) {
$permissions = $role->permissions;
foreach ($permissions as $perm) {
if ($perm->controller === $controller
&& $perm->action === $action) {
return true;
}
}
}
return false;
}
}
四、API Token认证中间件
class ApiAuth {
public function handle($request, \Closure $next) {
$token = $request->header('Authorization', '');
$token = str_replace('Bearer '', '', $token);
if (empty($token)) {
return json(['code' => 401, 'msg' => '未登录']);
}
// 验证Token
$userId = $this->validateToken($token);
if (!$userId) {
return json(['code' => 401, 'msg' => 'Token无效或已过期']);
}
// 将用户信息注入请求
$request->userId = $userId;
return $next($request);
}
private function validateToken($token) {
try {
$payload = JWT::decode($token, $key, ['HS256']);
return $payload->user_id;
} catch (\Exception $e) {
return false;
}
}
}
ThinkPHP6的中间件系统为权限控制提供了优雅的解决方案。通过合理设计中间件,可以将认证、授权等横切关注点与业务逻辑解耦,让代码更清晰、更易维护。