这里是文章模块栏目内容页
Thinkphp6用中间件实现多个控制器判断用户登录权限

    在做后台管理时,需要判断用户是否登录,是否具备控制器的action操作权限。实现此功能的办法很多中选择,开发过程中会依赖所使用的框架来构造实现逻辑,因此每个程序的框架在代码安排上有不同。本文描述thinkphp6框架下的实现思路,仅供参考。

 

    首先来概括一下思路方法。用户登录后,把账号信息保存sessioncookie里。Session保存的信息用作在程序的各个业务环节下获取当前账号信息。Cookie的信息用作,用户关闭浏览器离开站点,再次打开浏览器回到站点,通过读取cookie信息,恢复对应账号信息到session中。两者虽然都保存的是账号的id和密码,功能用途不一样。Cookie的信息可以设置成3天过期或者半个月过期,用户在这个过期时间内,访问站点都能自动登录。处于安全考虑,建议管理后台类的设置10分钟过期。而网站前端类型的可以设置永远不过期,用户打开浏览器即可看到用户名,但是点击进用户中心,需要进行密码验证。这样做即安全又有比较好的用户体验。

 

    Thinkphp6每个控制器 都有__construst()方法,在这个方法里面,先判断session是否存有用户信息,如果没有判断cookie里是否存在,如果也cookie里也没有,那么把访问redirect到登录页面。这样,在每个controller的结构函数里面做判断一下,即可实现用户登录权限限制。这个思路是正确的,但是代码相对来说是冗余一点了。把判断的代码写在一个公用函数里面呢?当然也是可以解决。但这样做,并没有发挥tinkphp6 的框架优势。

 

    怎么做呢?采用thinkphp的中间件 middleware来实现。在app应用的middleware目录新建一个 loginCheck类。

代码如下所示

class CheckLogin {
 
    public function handle($request, \Closure $next) {
        /**
         * 判断是否登陆的中间件
         */
        $user = $request->session('loginUser');
        
        if (empty($user)) {
            $ck_member = Cookie::get('member', null);
           
            if (!empty($ck_member)) {
                $user = json_decode($ck_member, true);
                $info = Db::table('users')->where(['id' => $user['id']])->find();
                if (!isset($info['username']) 
                        || ($info['username'] !== $user['username']) 
                        || ($info['password'] !== $user['password'])) {
                    return redirect(url('/user/index'));
                }               
                session('loginUser', $info);
            } else {
                return redirect(url('/user/index'));
            }
        }
 
        return $next($request);
    }
 
}

采用框架的控制器中间件规则,为需要判断用户登录权限的控制器启用中间件的判断;例如index控制器。

class Index extends BaseController
{
    public function initialize() {
        parent::initialize();
        $this->middleware = [
             \app\middleware\CheckLogin::class,
        ];
}


这样,在访问index控制器里任何方法之前,框架会先运行CheckLogin 的handle方法,判断用户登录权限。


好了,本文讲解了如何通过thinkphp6 中间件,控制器启用中间件的办法,判断cookie和seesion 数据,达到判断用户是否登录,相关权限的办法思路。


欢迎大家交流讨论,如何做一个权限控制表。下一个文章一起来实现thinkphp6 结合mysql数据库,把用户操作权限限制在控制器 controller 的每个action 上。