Take user back to previous page after logging in?

大憨熊 提交于 2019-12-20 01:41:36

问题


I have a controller called Accounts, with the views signin and signout.

The corresponding functions look like this:

function signin()
{
    if (!empty($this->data)) 
    {
        //handle login
        ...
        //save login to session
        $this->Session->write('Account',  $data["Account"]);
        //redirect to previous page
        ???
    }
}

function signout()
{
    //delete login
    $this->Session->delete('Account');
    //redirect to previous page
    ??? 
}

If the user goes to accounts/signin it first checks to see if the form is submited if(!empty($this->data)) if yes, it logs them in, if not it renders the signin form. If they do succesfully log in, I want to redirect them to the page they were at before the signin page.

Whats the best way to do that?

Edit:

I do not think I can user a regular http referrer because technically the referrer will always be the signin in page because they go to /signin, then submit the sign in form. So at the point where the form is submited the referrer is always /signin. I want to redirect to where they were before that. Does that make sense?


回答1:


http://book.cakephp.org/view/430/referer

Use a hidden <input> field that holds the initial referrer and gets submitted with the login data.




回答2:


the best way is to use cakes Auth component and let it do what it does... http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect




回答3:


Here's how I do it with referer

I have 2 login forms, one is a form at the top of all pages for easily sign in, the other is on login action. If the user comes in using the form at the top, the form submission then goes to login page and you can use $this->referer() to redirect the user back.

But the problem is that, if the user types the password wrong or enter invalid credential, he will then end up on the login page. If he then enters the right username+password, and redirection occurs using $this->referer(), which in this case is itself. The user then could then either 1. get redirected back to login page again or 2. even worse can get stuck in an infinite loop b/c login will keep redirecting to itself.

So, I add some logic to check to make sure that referer is not login page. Also, I add another logic to store $this->referer() the first time the user lands on login page, we we know where exactly the page before login page.

To store the page before login page, put this code at the end of the action (login view rendering is about to begin)

//get the current url of the login page (or current controller+action)
$currentLoginUrl = strtolower( "/" .$this->name ."/" .$this->action );
if( $this->referer() != $currentLoginUrl  )
{
    //store this value to use once user is succussfully logged in
    $this->Session->write('beforeLogin_referer', $this->referer($this->Auth->redirect(), true)) ) ;  //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead
}

Now put the code to redirect in the part of the code where authentication is succesful (or in if( $this->Auth->user() ){ } ):

//get the login page url again (by gettting its controller, or plural of Model, and this current page action and make the url)
$currentLoginUrl = strtolower( "/" .$this->name ."/" .$this->action );

//if the referer page is not from login page, 
if( $this->referer() != $currentLoginUrl  )
{
    //use $this->referer() right away
    $this->redirect($this->referer($this->Auth->redirect(), true));  //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead
}
else
{
    //if the user lands on login page first, rely on our session 
    $this->redirect( $this->Session->read('beforeLogin_referer') );
}

Hope this works for you.




回答4:


I don't know about the best way, but I store the attempted destination in a session variable before redirecting them to the sign in page.

Once they have signed in, I redirect them to the stored destination.




回答5:


Use the AppController and UsersController to set it up

In AppController beforeFilter action

$referer = Router::url($this->url, true);
$this->Auth->loginAction = array('controller'=>'users','action'=>'login','?'=>['referer'=>$referer]);

In UsersController login action

if($this->Auth->login())
{
 $this->Session->setFlash(__('Logged in successfully !'));
$redirect = $this->request->query('referer');
if(!empty($redirect))
 {
   return $this->redirect($this->Auth->redirectUrl($redirect));
 }else{
    return $this->redirect($this->Auth->redirectUrl());                 
 }
}



回答6:


CakePHP 2.x here

1. Edit AppController.php

public function beforeFilter() {
        // redirect url
        if($this->request->here!= '/users/login') {
            $user_id = AuthComponent::user('id');
            if(empty($user_id)) { $this->Session->write('redirect_url_after_login', Router::url($this->request->here, true)); }
}

This will store the url the user wanted to go before request, only if the url is not /users/login (replace with your url of login) AND if no user is logged.

2. Edit your login form. Mine was Users/login.ctp. Add an hidden field only if there is a session variable set.

    $redirect_url_after_login = $this->Session->read('redirect_url_after_login');
    if(!empty($redirect_url_after_login))
        echo $this->Form->input('redirect_url_after_login', ['value'=>$redirect_url_after_login, 'type'=>'hidden']);

3. In your login action, add an action to overwrite the loginRedirect variable you may have set before.

public function login() {
    if ($this->request->is('post')) {
        if ($this->Auth->login()) {
            $redirect_url_after_login = $this->request->data['User']['redirect_url_after_login'];
            if(!empty($redirect_url_after_login)
                &&filter_var($redirect_url_after_login, FILTER_VALIDATE_URL)
                &&parse_url($redirect_url_after_login, PHP_URL_HOST)==$_SERVER['HTTP_HOST'])
                    return $this->redirect($redirect_url_after_login);
            $this->Session->delete('redirect_url_after_login');
            return $this->redirect($this->Auth->redirect());

}

I added a couple of security checks, like "is the redirect url a valid url?" and "is it redirecting towards my domain or an external domain?".

Note: I know checking $_SERVER['HTTP_HOST'] is not bulletproof, but here we're talking about preventing open redirect vulnerability, so it's enough.



来源:https://stackoverflow.com/questions/4795430/take-user-back-to-previous-page-after-logging-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!