ThinkPHP6中间件与权限控制


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的中间件系统为权限控制提供了优雅的解决方案。通过合理设计中间件,可以将认证、授权等横切关注点与业务逻辑解耦,让代码更清晰、更易维护。


0.072628s