I have the following snippet of code that redirects a user to a specific page on successful login to the application.
if(isset($this->params['url']['next'])) {
$url = parse_url(urldecode($this->params['url']['next']), PHP_URL_HOST);
if( $_SERVER['SERVER_NAME'] != $url || $url == false ) {
$pathtoredirect = $this->Auth->redirect();
} else {
$pathtoredirect = urldecode($this->params['url']['next']);
}
} else {
$pathtoredirect = $this->Auth->redirect();
}
$this->redirect($pathtoredirect);
The idea is that if a query string named 'next' exists and has a valid hostname that matches the actual sever hostname then send the user to that location otherwise send them to the default location. It should also handle really bad formatted urls by the parse_url method returning false.
Can anyone see any issues with the above code? Or offer improvements?
Thanks
EDIT
The next parameter can be added manually for example on a login link, but is also created automatically on the redirect when a user tries to access a protected action.
The reason for adding the FULL_BASE_URL
is because the session also contains the app url, so if your app is on a subdirectory e.g. domain.com/myapp/
and you try and access domain.com/myapp/protectedlocation
you will get redirected to the login form with domain.com/myapp/login?next=/myapp/protectedlocation
which will then send you off to: domain.com/myapp/myapp/protectedlocation
adding /myapp twice! Doing the full url instead STOPS this from ever happening and doing the parse url prevents a malicious user from creating a login link with their own url as the return.
public function redirect($url, $status = null, $exit = true)
{
if($this->Session->read('Auth.redirect'))
{
$url.= '?next=' . urlencode(FULL_BASE_URL.$this->Session->read('Auth.redirect'));
}
$this->Session->delete('Auth.redirect');
return parent::redirect($url, $status, $exit);
}