PHP: Returning a user to their original page after

2020-02-26 03:30发布

问题:

Are there any 'best practices' concerning how one should return a user to their original page after logging in to your website, specifically in PHP? e.g. if I'm viewing a StackOverflow question while not logged in, how would you ensure that I return to this question if I logged in?

From my research, it seems a lot of advice centers around the $_SERVER['HTTP_REFERER'] variable. Basically, you take note of the referer and store it in the session, then redirect back to that page when you're done.

The problem with this is that HTTP_REFERER is unreliable at best.

This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.
— [http://php.net/manual/en/reserved.variables.server.php]

Any edits to the referer to redirect to other areas of the site will be handled by routine permissions checks. If the referer gets blanked out, it might be acceptable to simply redirect the user to the main page of the site rather than the page they came from. This seems needlessly user hostile though, and I was hoping there would be some better way to handle this.

回答1:

On login page:

<form action="controller/LoginController" method="post">
<?php

if (isset($_SERVER['HTTP_REFERER'])) {
  echo '<input type="hidden" name="l" value="'.htmlspecialchars($_SERVER['HTTP_REFERER']).'" />';
}

?>
<!-- the rest of the form -->
<input type="submit" />
</form>

At login controller, you take in the $_POST['l'] value and see whether or not this URL is on your own website. If it isn't, redirect to your default page, else redirect to this URL.

Make sure that on your login page if user is already logged in, you redirect the user back to home page or something. This will prevent cases like redirecting back to login.

$_SERVER['HTTP_REFERER'] is a browser responsibility. It is also most of the time rather reliable. If the browser doesn't send, or if you are worried about it, you can use session instead.

on every page simply set $_SESSION['lastvisitpage'] to the current page URL. On login then you redirect to $_SESSION['lastvisitpage'].

Since $_SERVER['HTTP_REFERER'] can be faked by a user at any time, one should always treat is any other user-supplied variable by properly escaping it.



回答2:

It would be better if you store the last visited page on your own, maybe with the help of a session.

If the user requests a page from your website the first time, start a new session and initialize last-URI with the current URI. Update this last-URI whenever another page is requested until it’s the login page. Now if the authentication is successful, you can redirect to user to the URI in last-URI.

And if you have a login form on every page, use a hidden input where the current URI is stored in.



回答3:

if(user_not_logged_in())
{
    $link = "http://example.com/login?continue=path/to/current/page";
    echo '<a href="'.$link.'">Loign</a>';
}

This is how I, and sites like Google, does it. You would need to make sure that you check the continue variable and sanitize it of weird URLs first however.

Another option is use AJAX, and allow the user to login from any page. User logs in, you submit the form via AJAX, refresh when the request comes back.


I think you might be asking if the user specifically clicks on the login link on a menu, you automatically think that the user wants to be redirected to the page that they pressed the button from. This I believe is a flaw in logic. Take StackOverflow. Just because I press login doesn't mean I want to return to the question I was last on.

However, there are some instances that it would be correct to assume the person wants to go back, such as if I upvoted a question and got the popup telling me to login. If I clicked the link there, it would be safe to assume that I want to go back. But just the login link on the nav bar doesn't have that implied meaning.



回答4:

I would suggest make an AJAX call to login the user and on successful AJAX response just refresh the current page.