How to set returnUrl?

This is what I want: A user visits a page, but he's not logged in. He is sent to the login page. After login, he is immediately sent to the page that he was initially trying to visit.

This is clearly what Yii::app()->user->returnUrl is for. But I'm having trouble setting this value. After login, Yii always redirects me to the index page (site/index) instead of the page I was trying to visit.

This is what I've done: I extended CController with a class called MyController and all my controllers inherit from that. MyController has the init function:



	public function init() {


		if (<the cookie has expired>) {


			Yii::app()->user->logout();


			Yii::app()->user->setReturnUrl($_SERVER['REQUEST_URI']);


			Yii::app()->request->redirect($this->createUrl('site/login'));


		}


	}


Then, after the login form, I sent the user to returnUrl:



	public function actionLogin() {


		$form = new MyLoginForm;


		if (isset($_POST['MyLoginForm'])) {


			$form->attributes = $_POST['MyLoginForm'];


			if ($form->validate())


	---->>		$this->redirect(Yii::app()->user->returnUrl);   <<-----


		}


		$this->render('login',array('form' => $form));


	}


What am I doing wrong? Isn't this how you set the returnUrl?

Thanks for the help.

You don’t have to set it. Yii does this automatically for you when you try to access an action that is protected by an access rule. It’s described in more detail in the guide. I think, you should also already have an example for this when creating your base application with yiic.

I am not currently using accessRules() but I'd be happy to try it. What I want to do is allow only users with a certain role to access the actions in a certain controller. I just tried using accessRules() and it didn't work. This is what I tried:



class StaffController extends CController {


	public function accessRules() {


		return array(


			array('allow',


				'actions'=>array('*'),


				'roles'=>array('Staff'),


			),


			array('deny',


				'actions'=>array('*'),


				'roles'=>array('*'),


			),


		);


	}


}


The idea is that only people with the 'Staff' role can do the actions in this controller. But when I tested, I was able to do the actions in this controller without being logged in at all.

Can you see what I'm doing wrong here?

Did you configure accessControl as filter in your filter() method?

Btw. you can simplify your rules like this:

<?php


      return array(


         array('allow', 'roles'=>array('Staff')),


         array('deny'),


      );


Thanks. No, I didn't. How do I do that? Would this work?



public function filters() {


        return array(


            'accessRules',


        );


}


Two more questions:

  1. Suppose that a user has role 'Engineer' which is a type of 'Staff'. Will the user get access to StaffController automatically? Or do I have to specify 'Engineer' as well. Let's assume that elsewhere I have already set


$role = $auth->createRole('Engineer');


$role->addChild('Staff');


  1. How did you get code highlighting into your post? I was trying to do that earlier and I couldn't figure out how.

Thanks for the help.

  1. ;) Yes, that’s what your filter method should look like

  2. Yeah, that should work, but you'll need to set up RBAC which requires a little more effort to set up. And you need to configure authManager in your main configuration. Again, you can find more details on RBAC in the guide. I'd suggest to understand everything before using it…

  3. Simply add a <?php at the beginning of your code block.

Yii hates me.    :(

Filter "accessRules" is invalid.


Controller "SiteController" does have the filter method "filteraccessRules".

Sorry, i was wrong: it should look like this, to make Yii love you:

<?php


    public function filters()


    {


        return array(


            'accessControl'


        );


    }


Thanks.

Hmm… well, there's definitely progress. Now I don't get a CException. But I do get an access-denied error:



Unauthorized


You are not authorized to perform this action.





You do not have the proper credential to access this page. 

I checked using a different page and I can confirm that I am logged in and that my account has the right permissions (using Yii::app()->user->checkAccess()). I'm scratching my head.

I guess, it's because you don't have configured the Role for that user yet.

For the returnUrl, you can call Yii::app()->user->loginRequired(), which will set the returnUrl for you and redirect the browser to the login page.

For access rules, you don't you need to put in anything in 'actions' if you want the rule to apply to all actions. The star character and other special characters are only used in 'users'.

Quote

I guess, it's because you don't have configured the Role for that user yet.

But I do! I have been using the roles for a couple of days now. The roles work just fine when I do it by hand. I can run Yii::app()->user->checkAccess() to restrict which actions the user can do and that has been working perfectly since the start. The only reason I began tinkering with accessRules is so I get the returnUrl feature.

Quote

For the returnUrl, you can call Yii::app()->user->loginRequired()

Yii::app()->user->loginRequired() works great. Thanks.

It's a shame that I couldn't get the accessRules thing working. That's so strange because I can check the permissions by hand with Yii::app()->user->checkAccess() and that has always worked right (returns 'true' when it should, returns 'false' when it should).

Anyways, thanks for the help.

What does your accessRules() look like now?

Oh, I deleted it because I needed to work on something else, but it looked like this:



<?php


// This controller has pages common to all users with accounts (not 'Guest').


class UserController extends MyController {


    public function filters() {


        return array('accessControl');


    }


    public function accessRules() {


        return array(


            array('allow', 'roles'=>array('User')),


            array('deny'),


        );


    }


According to your rules here, a user with 'User' role should be able to access any actions. And all other users won't be able to access any action.

What are you observing now?

I got an "unauthorized" error.



Unauthorized


You are not authorized to perform this action.





You do not have the proper credential to access this page. 

The user in question has the 'Manager' role, for whom 'User' is a child role. I just tested again, ding the same thing but with ManagerController:



<?php


// This controller has pages for managers only.


class ManagerController extends MyController {


    public function filters() {


        return array('accessControl');


    }


    public function accessRules() {


        return array(


            array('allow', 'roles'=>array('Manager')),


            array('deny'),


        );


    }


Same result.

I also checked the database, and this user does have the Manager role. I also checked for typos.

ah, i see. This is actual a bug about case-sensitivity of roles (specified in accessRules). It has been fixed in svn already.

Cool.  Is there a workaround I can use in the mean time? The role name really is 'Manager' with capital M. If I use 'manager' (lowercase m) in accessRules() will that work?

To answer my own question: No, changing to lowercase 'm' didn't help. :frowning: