The HyperText Transfer Protocol (HTTP) 401 Unauthorized response status code indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.
401 is the proper response code to send when a failed login has happened. 401 Unauthorized Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
A 403 error response indicates that the client's request is formed correctly, but the REST API refuses to honor it, i.e., the user does not have the necessary permissions for the resource. A 403 response is not a case of insufficient client credentials; that would be 401 (“Unauthorized”).
A 201 status code indicates that a request was successful and as a result, a resource has been created (for example a new page). The status code 202 indicates that server has received and understood the request, and that it has been accepted for processing, although it may not be processed immediately.
If you are strictly using the HTTP authentication framework provided by RFC 7235 for your REST API, the correct HTTP code would actually be 401. From the RFC:
The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server generating a 401 response MUST send a WWW-Authenticate header field (Section 4.1) containing at least one challenge applicable to the target resource.
If the request included authentication credentials, then the 401 response indicates that authorization has been refused for those credentials. The user agent MAY repeat the request with a new or replaced Authorization header field (Section 4.2).
Your REST API should employ an authentication scheme of some sort in order to return a valid 401 response to your client.
Another pertinent section from RFC 7235, page 4:
Upon receipt of a request for a protected resource that omits
credentials, contains invalid credentials (e.g., a bad password) or
partial credentials (e.g., when the authentication scheme requires
more than one round trip), an origin server SHOULD send a 401
(Unauthorized) response that contains a WWW-Authenticate header field with at least one (possibly new) challenge applicable to the
requested resource.
A higher-level response, such as a rendered login page for a visual user (redirected from a protected resource via 302), would be better served with the 200 status code (per @KernelDeimos' answer, for example). Since login pages are typically their own resource (e.g. /login?redirect=original-resource
), the unauthenticated user is still authorized to see this page, even if they provide an incorrect username/password. Then, you redirect the authenticated user back to the resource, at which point would show 200 if allowed, or 403 if the user is forbidden to view the resource.
The area where 401 could come into play with a visual login page is a front-end library that leverages the REST API using XHR requests, then relay the 401 response from the REST API back into a meaningful format on the login page.
401 - Unauthorized
403 - Forbidden
http://www.buggybread.com/2012/11/http-error-codes-401-access-denied-403.html
Use the appropriate status code in 2xx
for a successfully handled login request with the wrong password.
Before asking "what is the correct HTTP status code", it's important to consider this question: "Should success or failure of login be reflected in the HTTP status code of the response?"
In @sjagr's answer the first part of this section is highlighted. I'm going to highlight the second part and explain why:
If the request included authentication credentials, then the 401 response indicates that authorization has been refused for those credentials. The user agent MAY repeat the request with a new or replaced Authorization header field (Section 4.2).
This refers to an Authorization
header, rather than a request body containing login credentials. The phrasing of the first part, unfortunately, could be misinterpreted to refer to a request body containing login information. This ambiguity can be resolved by considering separation of concerns; (https://en.wikipedia.org/wiki/Separation_of_concerns) the server's response header should not depend on the differences of two valid request bodies, with the exception of when it causes an internal server error, otherwise the concerns of data transfer and appliction login begin to creep into each other.
I would use HTTP response 2xx
for a valid login request, where the client has permission to attempt a login, that is handled successfully with a response indicating success or failure.
I also like the way @spectras expressed this in the comments:
Attempting to express an application-level error in a transport-level status code is a design mistake.
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