admin管理员组

文章数量:1291295

I have a simple web application which has a login screen and an activity page which is only accessible when the user has supplied valid credentials. Assuming the user clicks on login with valid credentials and gets re-directed to the activity page.Now the user does not click on logout, instead he/she simply clicks on the back button of the browser and goes back to the login page. This behavior is obviously non-intuitive , I would assume while the user is logged in and he/she clicks on the back button to remain on the same page and not go back to the login page.

function loginUser(req, res) {
    if (req.session.auth) // if user is still authenticated
    {
        res.redirect('/activity');
    }
    res.render('login');
}

This is a simple way I use currently to always redirect the user back to the activity page, however I find this a resource wasteful method since there are unwanted redirections introduced. My question is , is this the standard and cleanest way to implement the above behavior or is there a better mechanism ? I am using passport for authentication and storing jwt tokens.

EDIT: To re-iterate the above solution works only if the browser no-cache is enabled, contrary to which the controller for the login route does not even get called since the browser has cached the page. I am looking for something more robust. I don't think it is good practice to hard-code the browser to not cache the page in a production environment.

I have a simple web application which has a login screen and an activity page which is only accessible when the user has supplied valid credentials. Assuming the user clicks on login with valid credentials and gets re-directed to the activity page.Now the user does not click on logout, instead he/she simply clicks on the back button of the browser and goes back to the login page. This behavior is obviously non-intuitive , I would assume while the user is logged in and he/she clicks on the back button to remain on the same page and not go back to the login page.

function loginUser(req, res) {
    if (req.session.auth) // if user is still authenticated
    {
        res.redirect('/activity');
    }
    res.render('login');
}

This is a simple way I use currently to always redirect the user back to the activity page, however I find this a resource wasteful method since there are unwanted redirections introduced. My question is , is this the standard and cleanest way to implement the above behavior or is there a better mechanism ? I am using passport for authentication and storing jwt tokens.

EDIT: To re-iterate the above solution works only if the browser no-cache is enabled, contrary to which the controller for the login route does not even get called since the browser has cached the page. I am looking for something more robust. I don't think it is good practice to hard-code the browser to not cache the page in a production environment.

Share Improve this question edited Aug 9, 2016 at 21:52 john smith asked Aug 7, 2016 at 2:00 john smithjohn smith 5176 silver badges19 bronze badges 2
  • 1 You can't control the browser or modify its history for obvious security reasons, so you're pretty much done. The only thing that could be missing is ensure your code checking if the user is logged or not is executed every time so you need to make sure that the login page can not be cached by the browser. – HiDeoo Commented Aug 9, 2016 at 10:07
  • You might want to consider JWT. See the Satellizer library on github. – Taylor Ackley Commented Aug 15, 2016 at 21:14
Add a ment  | 

4 Answers 4

Reset to default 3 +25

One of the "features" of (most) modern browsers is that clicking the back button navigates you back to the state at which that page was loaded. Unless you dynamically update the login page before navigating away to the logged in state, this is the experience you'll get.

What I'd suggest instead is once authenticated on the login page, instead of immediately redirecting the user to the logged in state, update the logged in page to indicate that the user is now logged in (e.g. if you have an avatar/profile icon in the top right, change the appearance of it with .js to indicate the user is logged in).

Once the state of the login view has been changed, then navigate to the appropriate content view (using a meta redirect might be the most appropriate, but you can do it how you like).

You can assume that because the user clicked the back button, they probably meant to. This solution ensures that the user's expectation of back-button behavior is respected, as opposed to forcing a redirect by detecting a cookie with js and re-navigating -- which leads to forward/back redirect loops (which are oh-so frustrating!)

While StackOverflow doesn't actually do what you're trying to do, here's an example of what you could do with .js to dynamically update /login before you navigate away:

Your solution seems fine. You might be able to improve your idea by using window.onbeforeunload and window.onunload events. Something like this:

<script type="text/javascript">
    window.onbeforeunload = onbeforeunload_handler;
    window.onunload = onunload_handler;
    function onbeforeunload_handler() {
        // Do something here
    }

    function onunload_handler() {
       // Or do something here
    }
</script>

I havn't test this out but I think it should work. Try js res.redirect('/activity?_='+ Date.now()); to prevent browser from using cached page.

You have a couple of solutions here.

One, would be to tell the browser not to cache /login. This makes sense for many reasons. About you concern of not wanting to disable cache in production, remember you'll be disabling cache just for the /login page, which is not as bad.

An alternative would be to add some JS code in the /login page that will see if a certain logged-in cookie exists. In case it does, just refresh the page. By refreshing the page, the back-end side will be executed and the redirection will actually happen.

I would go with the first one. For that particular route, something along these lines would do the trick (not tested).

res.set({
    'Cache-Control': 'no-cache, no-store, must-revalidate',
    'Pragma' : 'no-cache',
    'Expires' : '0',
})

本文标签: