I have a page that has ajax elements. If a user cicks an ajax link but his session has timed out, Yii returns the fully rendered loginUrl.
Instead, I’d like to customize this behavior and have a timed out session throw a 401 http exception and have jQuery handle the error with a redirect (and maybe display a nice ‘you have timed out’ message.
I don’t see where Yii actually performs the check. It appears to happen even before ‘beforeAction’ is parsed.
So I have my code that throws an exception in ‘beforeAction’ but it is never reached since Yii is redirecting before I can handle it myself.
I created WebUser.php in protected/components, then modified the config/main.php ‘user’ component to use the WebUser class.
Here is WebUser:
<?php
class WebUser extends CWebUser
{
public function loginRequired()
{
$app = Yii::app();
$request = $app->getRequest();
$this->setReturnUrl( $request->getUrl() );
if ( ($url = $this->loginUrl) !== null )
{
if (is_array($url))
{
$route=isset($url[0]) ? $url[0] : $app->defaultController;
$url=$app->createUrl($route,array_splice($url,1));
}
if ( $request->isAjaxRequest )
{
//$this->renderPartial('application.views.main.sessionTimeout', array(), false, true);
echo "This output is never given to the client...";
}
else
{
$request->redirect($url);
}
}
}
}
That should be what you have for the class as well, however Yii completely ignores this logic and the app continues to display a fully rendered login screen inside the update div.
I commented out the non-ajax redirect to see if the request would just die but somehow the app still managed to redirect itself to the login page and render into my update div. That’s true even if I use CWebUser. To say it another way…WTF?
All caches are cleared and disabled so I’m at a loss.
Well, you could verify that it’s actually running the method by adding in some Yii log statements or just straight up ending the app when it comes to that point. Depends on your frustration level
(Note: make sure you have logging info enabled in the config)
If you want to add some log statements, just at the very beginning of the loginRequired method, add:
and just have an action in the site controller that will pull up the partial you linked above. This way, it’ll still do the inset shenanigans it’s doing now, but instead of drawing the whole site in, you should get just the partial view in your update div.
’ loginRequired()’ was never getting called so I started looking at why that might be the case.
I extend from a BaseController to do some credentials and date range checking and in there I had code that redirected to the login page if the user was ‘guest’.
Instead of redirecting in that way, I now call Yii::app()->user->loginRequired when the user is guest and that solved the issue.
Duh. I caused my own unnecessary drama.
Your override works perfectly, Dana. Thank you very much for the help, it’s greatly appreciated =D