NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
[TOC] # 简介 前面提到判断用户登录用`Yii::$app->user->isGuest`来确定是否登录 但是通常大多数功能都要登录后才使用,那如果每一个站内功能都写这个if判断肯定是不现实 其实大家也能想到一些技巧来实现,比如定义一个控制器基类,在基类的init方法里做isGuest判断,所有控制器继承它就行了 # 方法1:官方推荐,用访问过滤器来判断 其实这并不是我最推荐的方式,但为了顺利把官方的基础知识学一下,我觉得有必要掌握一下这招 官方在过滤器封装好了一套登录校验逻辑,我们可以直接拿来配置一下就能用上,并且对于需求不断变化的应用来说,用这个比较好扩展 还记得[过滤器](http://www.kkh86.com/it/yii2/guide-base-filter.html)这篇文章里提到的过滤器吧,在做登录授权的时候就是使用官方自带的[yii\\filters\\AccessControl](http://www.yiichina.com/doc/api/2.0/yii-filters-accesscontrol)这个“访问控制”过滤器 好了我们假设有个控制器要用,那就在这个控制器里重写父类的behaviors方法: ~~~php public function behaviors(){ return [ 'access' => [ 'class' => 'yii\filters\AccessControl', 'rules' => [ //检测规则 [ //第1条规则 'roles' => ['@'], //角色集合,@表示登录用户 'allow' => true, //是否允许访问 ], [ //第2条规则 'actions' => ['login', 'register'], //针对本控制器的哪些方法ID生效,这两个ID就是针对actionLogin和actionRegister两个方法生效 'roles' => ['?'], //? 表示未登录用户 'allow' => true, //允许未登录用户访问 ], ], ], ]; } ~~~ 配置好后未登录状态下可以运行控制器的login和register方法,不能运行其它方法,会返回HTTP 403,这是访问控制过滤器的基本使用,晚点再慢慢深入掌握它 * #### 访问过滤器规则的封装 虽然重写behaviors方法使用过滤器就能实现登录检测,但这代码行数也不比自己写逻辑的少,而且还要每个控制器去配置这还得了? 那当然还是封装一个基础控制器,其它控制器继承它来实现继承过滤器规则咯 但这样增加了继承体系总感觉有点不好是吧,还可以这样,定义一个Trait,里面就是behaviors方法: ~~~php namespace app\lib; trait TraitCheckLogin{ public function behaviors(){ return [ 'access' => [ 'class' => 'yii\filters\AccessControl', 'rules' => [ //检测规则 [ //第1条规则 'roles' => ['@'], //角色集合,@表示登录用户 'allow' => true, //是否允许访问 ], [ //第2条规则 'actions' => ['login', 'register'], //针对本控制器的哪些方法ID生效,这两个ID就是针对actionLogin和actionRegister两个方法生效 'roles' => ['?'], //? 表示未登录用户 'allow' => true, //允许未登录用户访问 ], ], ], ]; } } ~~~ 然后在各个控制器里加上`use TraitCheckLogin;`就可以了(因为大部分程序员少接触trait这个知识点所以这样讲了) * * * * #### 配置登录地址 像上面这样使用了AccessControl过滤器后,在未登录的情况下访问时不会自动跳到登录页面,这样的用户体验不好 这里我们其实只要给user组件配置一下`loginUrl`就能让它自动跳过去了: ~~~php 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, 'loginUrl' => '/login.html', //!!!重点!!! //'loginUrl' => ['site/show-login'], //可以用数组,底层会拿去Url::to处理 //'loginUrl' => 'http://xxx.com/oauth.html', //甚至是绝对地址 ], ~~~ # 方法2:在app初始化的时候就做登录检测,适合中小型的典型应用 追加到配置文件第一层key(相关知识点:[在配置里定义事件](http://www.kkh86.com/it/yii2-adv/guide-base-listen-event-with-config.html)): ~~~php 'on beforeAction' => function($event){ if(!Yii::$app->user->isGuest){ //已经登录就随便他访问吧 return; } $isCommonAccessAction = in_array($event->action->controller->module->requestedRoute, [ 'user/register', 'user/login', 'site/error', 'site/captcha', ]); //是否不登陆可以访问 if(!$isCommonAccessAction){ $event->isValid = false; Yii::$app->response->redirect(Yii::$app->user->loginUrl); } } ~~~