Separate expired session redirects for different user types

Hi again

I have various types of user in my system and I’d like to redirect them to different pages when their sessions expire.

I’m not sure if this is possible as I can’t find anything about it in the docs.

Can anyone out there enlighten me?

Cheers

Huh, this is a really interesting question. The thing is, once the session expires, you don’t have access to it (duh XD) so you can’t really add a specific redirect.

But you could use a cookie to save the user type with a longer expiration time than the session.

Then in the AppController’s initialize function add something like:

public function initialize()
{
	parent::initialize();
	
	...

	$loginAction = $this->Cookie->read('user_type');
	
	$this->loadComponent('Auth', [
		'logoutRedirect' => [
			'controller' => 'Users',
			'action' => $loginAction
		],
		...
	]);
	
	...
}

Perhaps with more conditions to properly and securely define the logout redirect (with a default value).

Hi

Thanks for the response

I tried something a bit like this but it didn’t work. It only redirected to the page i wanted when i clicked the log out button. When i let the session expire it redirected to ‘users/login’.

I was reading through the docs this morning and it looks like it might be to do with how Auth handles unauthorised requests. By default it redirects to ‘users/login’ so i was wondering if setting ‘loginAction’ would cause it to redirect to another action. Maybe one that displays a session expired message and a few options.

But then the question is how to get it to redirect customers to a session expired page and admin users to the login page.

The only thing i can think of is using $this->referer() to get the page that made the request and comparing that against a list of urls to determine where to redirect to. Then maybe set the redirect with Auth->config(‘loginAction’). This last part is really messy though. There must be a better way!

I’ll try this out later and see how it goes.

Thanks again for posting. It’s very much appreciated.

Oh, right, I think what you need is the unauthorizedRedirect instead of the logoutRedirect, have you tried that?

Hi again

From the docs it looks like unauthorizedRedirect is a boolean that turns the default redirect for unauthorized access off.

I had a quick look at setting it to false and creating a custom error handler but then i was thinking i could just change the default redirect (by setting loginAction in Auth) to another function in my user controller. Then i could add some logic to establish where a request should be redirected to.

I think the problem here is how to do that. The only way i can think of – since the session will have expired and there wont be any session info – is to check $this->referer() to see where the request came from.

That would allow me to redirect unauthorized requests from the booking pages to a session expired/start again page, and redirect the rest to the admin login. I was also wondering if $this->referer() is null if i just type a url into the address bar. That would be useful for an access denied page or something.

I think this could solve my problem. It’s just the process of comparing known urls to $this->refere that seems messy and slow.

Maybe there’s a better way to do that.

No, you can definitely use unauthorizedRedirect to redirect users when they try to access a section they’re not supposed to - it’s just that the documentation is a bit confusing (as it often is…). I’ve tested it just now, so I’m certain :smiley:

You can simply debug $this->request->referer() to see how it behaves. But yeah, it seems like a very awkward solution.
The other one I can think of would be to add a get parameter to every link on protected pages, such as ?user=moderator

But this, too, would probably be rather annoying.

I still think the cleanest way to deal with it would be to set a cookie that lasts much longer than the session (weeks or months) which contains only the usertype.

Then you can simply add a bit of additional code to your isAuthorized functions where you return a redirect to the appropriate pages (instead of a return false).

Hi

Thanks for the response.

I tried this out this morning and i got the unauthorizedRedirect to work for a user with a valid session.

This is definitely useful as i can check to see if the user owns the record he is trying to access there.

However i wasn’t able to get it to redirect a user who’s session had expired.

I still haven’t tried returning a redirect from the isAuthorized function but I’ll give that a go later.

Thanks for your help on this the docs are definitely a little confusing in this area.

Hi again

I’ve been fiddling with this for a while and i can only get unauthorizedRedirect to work when a user with a valid session tries to access something they shouldn’t.

As i said this is very useful and has highlighted a hole in my security but the only way i can get my app to redirect a request when the users session has already expired is to put logic for it in the login function.

I tested it by putting a redirect right at the start of the isAuthorized function and waiting for the session to expire, but it still redirected to the /users/login!

Fascinating :smiley:
But I guess that kind of makes sense, if you think about it… Although it would have been nice if we could choose something different than the login action for logged out users :confused:

In any case, here’s another thought: How about you simply forget about redirecting the user, and simply change the view for the login page, depending on the user role.

So for instance, if the user is logged out and there’s no cookie, the login action will render the basic view.

However, if the user logs out or the session expires (which is for all intents and purposes the same thing), the login action will determine which view should be rendered based on the cookie that was stored on log in.

For example, you could show a dedicated content block above the login form, or remove the form altogether and add a button like “Please sign in again here”, which will delete the cookie and thus show the normal log in form.