Skip to content

Instantly share code, notes, and snippets.

@r3verser
Last active December 7, 2022 08:22
Yii2 Redirects all users to login (or any) page if not logged in, but allow access to some pages (like signup, password recovery etc.)
<?php
/*
* In configuration file
* ...
* 'as AccessBehavior' => [
* 'class' => 'app\components\AccessBehavior',
* 'allowedRoutes' => [
* '/',
* ['/user/registration/register'],
* ['/user/registration/resend'],
* ['/user/registration/confirm'],
* ['/user/recovery/request'],
* ['/user/recovery/reset']
* ],
* //'redirectUri' => '/'
* ],
* ...
*
* (c) Artem Voitko <r3verser@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file https://gist.github.com/r3verser/3094c7f045af46e2f9c3807a54c91026
*/
namespace app\components;
use yii\base\Behavior;
use yii\console\Controller;
use yii\helpers\Url;
/**
* Redirects all users to defined page if they are not logged in
*
* Class AccessBehavior
* @package app\components
* @author Artem Voitko <r3verser@gmail.com>
*/
class AccessBehavior extends Behavior
{
/**
* @var string Yii route format string
*/
protected $redirectUri;
/**
* @var array Routes which are allowed to access for none logged in users
*/
protected $allowedRoutes = [];
/**
* @var array Urls generated from allowed routes
*/
protected $allowedUrls = [];
/**
* @param $uri string Yii route format string
*/
public function setRedirectUri($uri)
{
$this->redirectUri = $uri;
}
/**
* Sets allowedRoutes param and generates urls from defined routes
* @param array $routes Array of allowed routes
*/
public function setAllowedRoutes(array $routes)
{
if (count($routes)) {
foreach ($routes as $route) {
$this->allowedUrls[] = Url::to($route);
}
}
$this->allowedRoutes = $routes;
}
/**
* @inheritdoc
*/
public function init()
{
if (empty($this->redirectUri)) {
$this->redirectUri = \Yii::$app->getUser()->loginUrl;
}
}
/**
* Subscribe for event
* @return array
*/
public function events()
{
return [
Controller::EVENT_BEFORE_ACTION => 'beforeAction',
];
}
/**
* On event callback
*/
public function beforeAction()
{
if (\Yii::$app->getUser()->isGuest &&
\Yii::$app->getRequest()->url !== Url::to($this->redirectUri) &&
!in_array(\Yii::$app->getRequest()->url, $this->allowedUrls)
) {
\Yii::$app->getResponse()->redirect($this->redirectUri)->send();
}
}
}
@coobic
Copy link

coobic commented Feb 20, 2016

Small note from contributor:
As i can see in docs:

\Yii::$app->getResponse()->redirect($this->redirectUri);

Only add Header to Response, but not redirect user immediately to login page and asked controller still execute!
So you must add ->send() and (i don`t now why exit(0), because return true or false was not working).
Final code:

\Yii::$app->getResponse()->redirect($this->redirectUri)->send();
exit(0);

@r3verser
Copy link
Author

@coobic you are right, have added ->send(), thanks!

@LarryMarzanJr
Copy link

LarryMarzanJr commented Nov 20, 2016

@r3verser so how do we use this, tehcnically, is there any manuals?
I'm using Yii2 advanced template.
thanks

@jscuba
Copy link

jscuba commented Aug 6, 2019

@r3verser I like this, thank you. Is there a license? I see some people do this for gists: https://gist.github.com/martinbuberl/c0de29e623a1e34d1cda7e817d18bafe

@r3verser
Copy link
Author

r3verser commented Aug 6, 2019

@r3verser I like this, thank you. Is there a license? I see some people do this for gists: https://gist.github.com/martinbuberl/c0de29e623a1e34d1cda7e817d18bafe

Hi! I have updated gist to MIT license, thanks!

@strtob
Copy link

strtob commented Dec 7, 2022

Nice behavior, thank you!

to make this work with parameter urls I've changed the beforeAction as following:

$requestUrl = strtok(\Yii::$app->getRequest()->url, '?');

    if (\Yii::$app->getUser()->isGuest &&
        \Yii::$app->getRequest()->url !== Url::to($this->redirectUri) &&
        !in_array($requestUrl, $this->allowedUrls)
    ) {
        \Yii::$app->getResponse()->redirect($this->redirectUri)->send();
        exit(0);          
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment