I am implementing the authentication for an app, and I am using a pluggable system with "authentication methods". This allows me to implement both HTTP Basic as well as HTML-based authentication.
With HTTP Basic/Digest auth the server sends a 401 Unauthorized
response header. However, according to the HTTP/1.1 RFC:
The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource.
Since I do not know of any "html" WWW-Authenticate header, sending a 401
with an HTML login form seems inappropriate. Is there any alternative to this? I want to design my app in a RESTful way.
What is the correct HTTP Status code (and headers) for an HTML-based login form? And what is the correct code when the login fails?
Note: I am not interested in Digest Authentication.
@2016-02-17 Updated
The
login form
http status should be200 OK
.The
error
http status better use401 Unauthorized
. (The name may be confused, 401 is about authentication. RFC7235If you want to handle if no permission right, you may need
403 Forbidden
[RFC7231]HTTP 422 is used for WebDAV, but the meaning might fit the needs. (Not suggested for most cases)
For more information, please see the comment of
Cássio Mazzochi Molin
below.@2016-02-12 Updated (This is the reference to the accepted answer.)The
login form
http status should be200
.The
error
http status better use400
.HTTP 422 is used for WebDAV, but the meaning might fit the needs. HTTP 401 is for authorization. And is not suitable for authentication.
@2016-02-12 Original
HTTP 422 is now better choice other than 400 / 401. HTTP 422 is an alternative choice.Because it means the server understand the data but is not correct for part of the data. i.e. It can show client that username / password incorrect.
RFC4918
For HTML I think you should respond with a 400.
This may be true for non-HTML requests as well, since 401 is as far as I understand it more designed to respond to a request to content that requires authentication, not to respond to an authentication request.
HTML does not always allow for pure use of RESTful APIs, so it's ok to cut corners here and there imo, but maybe there is a better way I'm not seeing in this particular case.
What about this one ?
When requesting the login form which is a public page, you get what you want, so it's a 200 status code :
When requesting for a page that needs a http level authentication that you didn't initiated (basic http, ssl certificate, etc.), the application must tell the browser itself that it needs to initiate this authentication for you :
When the authentication is a cookie-based session, you already have a cookie (if it's not the case, you will get one with the set-cookie header when requesting the page) but this cookie doesn't tell that you are allowed to access the
/secured
uri. So if you try to access this uri, you should get a "403 forbidden" status. Then the "log in" action is no more than just changing the state of the application with a POST request to make the application grant access for this cookie, so...Log in with bad credentials:
Log in with good credentials but not enough permissions :
Log in with good credentials and enough permissions :
This is a tricky question, largely because the most well-established HTTP clients used by people are browsers. According to the RFC, the
WWW-Authenticate
header can contain anything. Basic and digest authentication are just two examples of further standardised challenge/response mechanisms. You can simply specify a challenge likehtml-form id=foo
and return the401
along with an HTML form. Also, recall from the spec that multiple challenges can be specified within the sameWWW-Authenticate
header, but I don't have any experience testing browsers extensively with different schemes.