问答详情
源自:-

我有一个非常大的问题!!

在User控制器中有一个actionVlogin方法,这个方法主要的功能是检查Url的参数并设置cookie的。然而User控制器时继承Base控制的,base控制器中有个beforeAction方法,这个方法主要的作用是检查权限,并且在所有继承Base控制器的控制器里面的所有方法之前执行。

我的问题是:既然User控制器时继承Base控制器的,所以User控制器里面的actionVlogin方法在beforeAction方法之后执行。

当我们在导航条敲下/User/Vlogin?uid=1时,先跑的是beforeAction方法,此刻还没有跑到actionVlogin方法。因为是有先后顺序的,所以在

跑到beforeAction方法时,Cookie还没有进行设置(Cookie在actionVlogin方法设置)。所以你在beforeAction方法里面的所有检查都好像是

徒劳的,因为此时并没有Cookie。然而你把全部代码都写完权限功能却是好用的,为什么?是我理解错了吗?


求大神指教~~


求大神指教~~求大神指教~~

提问者:慕斯9981659 2018-03-01 13:23

个回答

  • 程序小工
    2018-08-27 16:25:29

    BaseController的beforeAction()可以看做有三个功能:

    1. 登录状态校验。 

      注意到beforeAction()的开始几句:

       $login_status = $this->checkLoginStatus();
       if ( !$login_status && !in_array( $action->uniqueId,$this->allowAllAction )  ) {
           if(Yii::$app->request->isAjax){
               $this->renderJSON([],"未登录,请返回用户中心",-302);
           }else{
               $this->redirect( UrlService::buildUrl("/user/login") );//返回到登录页面
           }
           return false;
       }

    逻辑是:如果用户已经登录(有cookie), 则获取用户的权限列表; 如果没有登录,则重定向到登录模块(也就是说User的Vlogin())。

    但是

    !in_array( $action->uniqueId,$this->allowAllAction )

    时排除了login和vlogin两个方法的,也就是说访问vlogin时,不会进入到这块的判断跳转。所以继续向下执行。

     2. 记录到访问日志。

    也就是说`$model_log`处理的那一段。[直接写入,不需要校验]

    3. 验证访问权限。

    if( !$this->checkPrivilege( $action->getUniqueId() ) ){    
        $this->redirect( UrlService::buildUrl( "/error/forbidden" ) );    
        return false;    
    }

    但是 checkPrivilege()方法有下面一段:

    if( in_array( $url,$this->ignore_url ) ){    
        return true;    
    }

    所以vlogin()的访问权限也不会进行校验。


    所以,综上,访问Vlogin()时,beforeAction()的作用仅仅是记录访问日志,并没有什么关于cookie的校验,所以也不存在徒劳之说。

  • 慕粉4153397
    2018-03-26 17:22:31

    。。。