This question is a question about login flows for web-apps in general. I'm most interested in answers that optimize for usability and performance while maintaining security.
To demonstrate the problem, here are some routes and respective behaviors for an example application:
GET /login -> Display the authentication form
POST /processLogin -> process the username and password,
if unauthentic...re-render the login form;
otherwise...display the default page
GET /secret -> if authenticated...display the secret resource;
otherwise...display a login form
POST /secret -> if authenticated...perform a desirable, but potentially
non-idempotent action on the secret
resource
otherwise...display a login form
Analysis: Hopefully, your client is a modern browser, non-compliant with HTTP, such that it performs a GET after a 302'd POST. This applies across the board. Should I be worried?
Analysis: Same problems as above. Added problem that the URL displayed by the browser during login changes, which is confusing to the user and breaks bookmarking, link sharing, etc.
Analysis: Sadly, the refresh button is now also broken: refresh will cause the user agent to re-POST with a warning, instead of re-GETing /secret. They user gets a warning, but if they ignore it, something bad happens.
On the bright side, you minimize roundtrips with this technique.
Analysis: Same problems as options 2+4.
Is there another technique I'm missing?
What is correct HTTP status code when redirecting to a login page? What kind of HTTP redirect for logins? HTTP response with redirect, but without roundtrip?
Description. Page to which users are automatically redirected after completing a successful authentication.
The most common ways to implement redirection logic after login are: using HTTP Referer header. saving the original request in the session. appending original URL to the redirected login URL.
In HTTP, redirection is triggered by a server sending a special redirect response to a request. Redirect responses have status codes that start with 3 , and a Location header holding the URL to redirect to. When browsers receive a redirect, they immediately load the new URL provided in the Location header.
Avoid chained redirects: one redirect should not forward to another redirect. Redirect to the preferred version of your website, using the right protocol (http or https), domain name (www or non-www) and path notation (with or without trailing slash). Use a 302 redirect for inactive campaigns.
Option 1 & 3 are not following the HTTP RFC as "surreptitiously display login form" contradicts 200 GET response, where "an entity corresponding to the requested resource is sent in the response" is expected.
Option 2 is OK. All modern browsers support 302 on POST and many REST-based frameworks (like RoR) actively use it. Alternatively in "302 to /login" you can already create the session (cookie) and store the URL in session, to avoid passing the original URL in GET parameters. From usability standpoint, you can have an appropriate message on login page too (I think the URL mismatch is irrelevant here - you can't let the user see the content anyway).
Option 4: when you POST to /secret, HTTP RFC expects you to "accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line", but all you are doing is logging in and not creating anything new under /secret.
So following HTTP RFC, your best choice is Option 2. Actually Option 2 is also in line with POST->Redirect->GET design pattern, which helps to address the issue of unpredictability in bookmarking URLs to POST'ed resources.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With