Yii Framework Forum: Redirect to login for guest users in every controller - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Redirect to login for guest users in every controller Rate Topic: ***** 1 Votes

#1 User is offline   jpablo 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 33
  • Joined: 18-August 11
  • Location:Rosario, Argentina

Posted 08 September 2011 - 11:49 PM

Hi! I found that beforeAction() can be used to hold the code to check if the user is not logged in, and then redirect the user to the login page with something like this:

if(Yii::app()->user->isGuest) $this->redirect(Yii::app()->getModule('user')->loginUrl);

But to have it working in the whole site I need to put this code in every beforeAction() in every Controller!

In a backend application the guest user can not even see the app menu, a non autenticated user can only access the login page. It's a tipical scenario. Every controller should be protected for guest users.

For a backend application this behavior may be desirable for every controller, there is a way to write the code just once, in a single place, instead of adding the beforeAction() to each Controller?
0

#2 User is offline   Greg Molnar 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 47
  • Joined: 17-January 11

Posted 09 September 2011 - 01:38 AM

There is a kinda master contoller in your components folder. You can set a beforeFilter there application wide.
0

#3 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 689
  • Joined: 12-September 10
  • Location:Austria

Posted 09 September 2011 - 01:39 AM

The Access Control Filter will do the work for you and redirects to the configured user->loginUrl (config/main.php) if a action is not allowed.

Add the rule
 
             array('deny',
                'users'=>array('?'),
            ),


to your base controller (f.e. 'Controller') where all your controllers are inherited from.

See this wiki article too: Access rules to default deny
0

#4 User is offline   jpablo 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 33
  • Joined: 18-August 11
  • Location:Rosario, Argentina

Posted 09 September 2011 - 12:11 PM

Joblo, Greg, many thanks! Your suggestion works for me =)

But I found a little issue..
If I deny access to every non autenticated user in every controller, Yii will redirect to the login controller/action. But this controller also has the access denied! This condition creates an infinite loop of redirects to the login form.

I can avoid it explicitly allowing access to every user to the login controller, like this:

array('allow', // allow authenticated users to access all actions
'controllers'=>array('user'),
'actions'=>array('login'),
'users'=>array('*'),
),

but it doesn't work... If I just define the 'login' action (removing the "'controllers'=>array('user')," line)it works fine, but also defining the controller to narrow the rule will lead to a no-match. Maybe a sintax issue?

If I just specify the login action the system will allow access to any action called "login", no matter the related controller.
0

#5 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 689
  • Joined: 12-September 10
  • Location:Austria

Posted 11 September 2011 - 04:10 PM

Why don't you override the accessrules from the base-controller in the user-controller?
I wouldn't add 'controllers' to the access rules. Maybe this helps.
0

#6 User is offline   logos010 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 12-November 10
  • Location:VietNam

Posted 26 April 2012 - 03:12 AM

Hi Jpablo,

I have a solution, why don't you check in beforeAction() of controller.

I've tried and it works for every Guest users, they will be redirected to login page.

public function beforeAction()
{
       if (Yii::app()->user->isGuest)
            $this->redirect(Yii::app()->createUrl('user/login'));

       //something code right here if user valided
}


Hope that help.
0

#7 User is offline   Jona Sauli 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 12-January 13

Posted 26 January 2013 - 11:21 AM

For whom who still havent solved this issue , add the following condition before loading the index page at the SiteController file.

public function actionIndex()
	{
		
       if (Yii::app()->user->isGuest)
        $this->redirect(Yii::app()->createUrl('site/login'));
	else
	$this->render('index');
	}

0

#8 User is offline   seenivasan 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 620
  • Joined: 17-June 12
  • Location:Chennai,TamilNadu,India.

Posted 26 January 2013 - 12:31 PM

Dear Friends.

We can use a behavior to to acheive the things.

Create ApplicationBehavior.php put inside the components folder.

components/ApplicationBehavior.php
<?php
class ApplicationBehavior extends CBehavior
{	private $_owner;
	
	public function events() 
        {

                    return  array(
			       'onBeginRequest'=>'denyEverything',     
			        
		        );
        }
	
	public function denyEverything()
       {
		$owner=$this->getOwner();
		if($owner->user->getIsGuest())
			$owner->catchAllRequest=array("site/login");
       }
}
?>


Then attach the behavior as a property to the application.
main.php
'behaviors'=>array(
    'class'=>'application.components.ApplicationBehavior',
      ),


Now if user is guest all the requests are landed at site/login.

Regards.
0

#9 User is offline   skworden 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 174
  • Joined: 14-June 12
  • Location:Virginia, USA

Posted 26 January 2013 - 12:38 PM

If anyone is having trouble with this and if you tying to force users login before they can view/do anything. You can do something like this:

Forcing login

Pretty much what seenlvasas said.

I use a variation of this and works well. I also added something like this to my main config file to manage sessions.

'components'=>array(
                
            //forces user to login after 20 minutes of inactivity.  
            'session' => array(
               'class' => 'CDbHttpSession',
               'timeout' => 1200,
            ),
	         'user'=>array(
                    // enable cookie-based authentication
                    'class' => 'WebUser',
                    'allowAutoLogin'=>false,
                    'autoRenewCookie' => true,
                    'authTimeout' => 86400, //kills session after 24 hours just in case above fails or if a user clicks remember me it will only last for this duration.
                    'loginUrl' => array('/user/login'),
                ),


here is my exact RequireLogin.php note i'm using yii-user and the captcha image dosen't render on login but i don't use it anyways.

<?php
class RequireLogin extends CBehavior
{
    public function attach($owner)
        {
            $owner->attachEventHandler('onBeginRequest', array($this, 'handleBeginRequest'));
        }
        
    public function handleBeginRequest($event)
        {
            $app = Yii::app();
            $user = $app->user;
            $recovery = trim(is_array(Yii::app()->getModule('user')->recoveryUrl) ? Yii::app()->getModule('user')->recoveryUrl[0] : Yii::app()->getModule('user')->recoveryUrl, '/'); //gets recovery url for yii-user
            $registration = trim(is_array(Yii::app()->getModule('user')->registrationUrl) ? Yii::app()->getModule('user')->registrationUrl[0] : Yii::app()->getModule('user')->registrationUrl, '/'); //gets reistraion url for yii-user
            $captchUrl = trim(is_array(Yii::app()->getModule('user')->captchaUrl) ? Yii::app()->getModule('user')->captchaUrl[0] : Yii::app()->getModule('user')->captchaUrl, '/'); //gets captcha url for yii-user..dosen't work?!?
            $request = trim($app->urlManager->parseUrl($app->request), '/');
            $login = trim($user->loginUrl[0], '/');
            $login = trim(is_array($user->loginUrl) ? $user->loginUrl[0] : $user->loginUrl, '/'); //gets loginurl from main config file

            // Restrict guests to public pages.
            $allowed = array($login,$recovery,$registration,$captchUrl);//allows users if not logged in to view only these 4 pages you can add others like above or like array($login,'site/login'); either way works. This is easier than adding to each controller if you only want users to be able to view a few pages w/o logging in.
            if ($user->isGuest && !in_array($request, $allowed))
            $user->loginRequired();
            
            // Prevent logged in users from viewing the login page.
            $request = substr($request, 0, strlen($login));
            if (!$user->isGuest && $request == $login)
            {
            $url = $app->createUrl($app->homeUrl[0]);
            $app->request->redirect($url);
        }
    }
}
?>


My url manager also looks like this (displays urls like : myproject.com/products/create)

// uncomment the following to enable URLs in path-format
		'urlManager'=>array(
			'urlFormat'=>'path',
                        'showScriptName'=>false,
                        'caseSensitive'=>false, 
			'rules'=>array(
				'<controller:\w+>/<id:\d+>'=>'<controller>/view',
				'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
				'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
			),
		),



This should help someone out!
0

#10 User is offline   TimT 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 01-July 12

Posted 20 February 2013 - 06:47 PM

I used the code from logos010 which was very close to working. I created this simple solution which worked for me.

In "myController" which extends "CController" I added this method:

	public function beforeAction()
	{
		Yii::app()->user->setReturnUrl(Yii::app()->request->getUrl());
		if (Yii::app()->user->isGuest && $this->id != "site")
			$this->redirect(Yii::app()->createUrl('site/login'));
	
		//optionally include code here if its an authenticated user
		return true;
	}


The differences from logos010's code are
  • the "return true" at the end - this code doesn't work if you leave that out,
  • checking for the current controller id to avoid an infinite loop on the redirect.
  • I also assume that the login (and other non-auth pages) are under "site" so this is changed too.
  • Stored the current Url into "returnUrl" so the user automagically comes back here after login

0

#11 User is offline   savariya 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 19-February 13
  • Location:india

Posted 15 May 2013 - 06:19 AM

hi seenivasan

your solution is working fine but i have one problem with that,
i m unable to get captcha image at login page.

do you have any solution for that plz inform me
0

#12 User is offline   Santosh S 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 12-October 13

Posted 22 October 2013 - 10:19 AM

I was facing the same problem wherein Captcha image was not getting displayed .
I solved the issue with following code (by checking that current request URL doesnt contain captcha word)

public function beforeAction()
{
Yii::app()->user->setReturnUrl(Yii::app()->request->getUrl());
$requestUrl=Yii::app()->request->url;
if (Yii::app()->user->isGuest && ( strpos($requestUrl, 'captcha') == null ) )
$this->redirect(Yii::app()->createUrl('site/login'));

//optionally include code here if its an authenticated user
return true;
}
0

#13 User is offline   Ankur Garg 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 23-September 14

Posted 23 September 2014 - 01:37 AM

Hi Friends

The simplest way to achieve this stuff. Just add the below function in component/Controller.php

public function beforeAction(CAction $action)
{
if(!isset(Yii::app()->user->user_id) && !($action->controller->id == 'site' && $action->id == 'login'))
{
$this->redirect(array('site/login'));
}
return true;
}
No need to add the beforeAction() in every controller.
Yii::app()->user->user_id
Here user_id can be any session variable.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users