Yii2 Dektrium用户,需要登录所有操作和所有控制器

时间:2016-03-02 15:35:15

标签: php yii yii2 yii2-user

为我在Yii2 require all Controller and Action to login中所说的所有控制器和操作进行登录,并将以下代码添加到web.php

'as beforeRequest' => [
        'class' => 'yii\filters\AccessControl',
        'rules' => [
                [
                        'allow' => true,
                        'actions' => ['login', 'forgot'],
                ],
                [
                        'allow' => true,
                        'roles' => ['@'],
                ],

        ],
        'denyCallback' => function () {
                return Yii::$app->response->redirect(['user/login']);
        },
],

但问题是所有其他操作如忘记密码都被重定向到登录页面,我想从登录所需条件中排除用户/忘记路由。请帮忙!

谢谢

2 个答案:

答案 0 :(得分:1)

我知道我要晚3年了,但这对其他寻找此答案的人可能有用:)

在config / web.php

$config => [
/* ... */
    'as AccessBehavior' => [
    'class' => 'app\components\AccessBehavior',
    'allowedRoutes' => [
        '/auth/register',
        '/auth/forgot',
        '/auth/resend',
    ],
    'redirectUri' => '/auth/login',
],
/* ... */

然后在根项目中创建一个“ components”文件夹,并使用以下代码创建一个“ components \ AccessBehavior.php”文件:

<?php

namespace app\components;

use Yii;
use yii\base\Behavior;
use yii\console\Controller;
use yii\helpers\Url;

class AccessBehavior extends Behavior
{
    protected $redirectUri;
    protected $allowedRoutes = [];
    protected $allowedUrls = [];

    public function setRedirectUri($uri)
    {
        $this->redirectUri = $uri;
    }    
    public function setAllowedRoutes(array $routes)
    {
        if (count($routes)) {
            foreach ($routes as $route) {
                $this->allowedUrls[] = Url::to($route);
            }
        }
        $this->allowedRoutes = $routes;
    }
    public function init()
    {
        if (empty($this->redirectUri)) {
            $this->redirectUri = Yii::$app->getUser()->loginUrl;
        }
    }   
    private function removeParams()
    {
        //enabled pretty url
        if (strpos(Yii::$app->getRequest()->url, "?") === false) 
        {
            $requestUrl = explode('/', Yii::$app->getRequest()->url);
            $params = array_values(Yii::$app->getRequest()->queryParams);
            $result = implode('/', array_diff($requestUrl, $params));
        } 
        else 
        {//not enabled pretty url
            $result = explode("?", \Yii::$app->getRequest()->url);
        }
        return $result;
    }    
    public function events()
    {
        return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
    }

    public function beforeAction()
    {
        $requestUrl = $this->removeParams();
        if (Yii::$app->user->isGuest)
        {
            if ($requestUrl !== Url::to($this->redirectUri) && !in_array($requestUrl, $this->allowedUrls))
            {
                Yii::$app->getResponse()->redirect($this->redirectUri)->send();  
                exit(0);
            }
        }
    }
}

此代码仅检查用户是否已登录并检查请求的路由。如果来宾用户正在访问允许的路由(您可以在配置中添加允许的路由)则不执行任何操作,否则会将用户重定向到登录页面:) 在上面的代码中,我将dektrium前缀路由设置为“ auth”。当然,在允许的路由中,您必须设置实际用于使用户注册,确认和更改密码的路由。

答案 1 :(得分:0)

没有测试过,但它应该有用。

'denyCallback'=>function() {
          if($this->action->id == 'forgot')
                return Yii::$app->response->redirect(['whatever/whatever']);
          else
                return Yii::$app->response->redirect(['user/login']);
},...
相关问题