RESTful Login Failure: Return 401 or Custom Response

rest api error codes
401 error
login failed rest api facebook
web api return status code with message
http response
rest post response
http 201 vs 200
401 unauthorized rest api

This is a conceptual question.

I have a client (mobile) application which needs to support a login action against a RESTful web service. Because the web service is RESTful, this amounts to the client accepting a username/password from the user, verifying that username/password with the service, and then just remembering to send that username/password with all subsequent requests.

All other responses in this web service are provided in a JSON format.

The question is, when I query the web service simply to find out whether a given username/password are valid, should the web service always respond with JSON data telling me its successful or unsuccessful, or should it return HTTP 200 on good credentials and HTTP 401 on bad credentials.

The reason I ask is that some other RESTful services use 401 for bad credentials even when you're just asking if the credentials are valid. However, my understanding of 401 responses are that they represent a resource that you are not supposed to have access to without valid credentials. But the login resource SHOULD be accessible to anyone because the entire purpose of the login resource is to tell you if your credentials are valid.

Put another way, it seems to me that a request like:

myservice.com/this/is/a/user/action 

should return 401 if bad credentials are provided. But a request like:

myservice.com/are/these/credentials/valid

should never return 401 because that particular URL (request) is authorized with or without valid credentials.

I'd like to hear some justified opinions one way or the other on this. What is the standard way of handling this, and is the standard way of handling this logically appropriate?

First off. 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. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.

Your confusion about, myservice.com/are/these/credentials/valid sending back 401 when you just do a check, I think is based on the fact that doing boolean requests in REST often is wrong by the RESTful constraints. Every request should return a resource. Doing boolean questions in an RESTful service is a slippery sloop down to RPC.

Now I dont know how the services that you looked on is behaving. But a good way of solving this is to have something like an Account object, that you try to GET. If you credentials are correct, you will get the Account object, if you don't want to waste bandwidth just to to a "check" you can do a HEAD on the same resource.

An Account Object is also a nice place to store all those pesky boolean values that otherwise would be tricky to create individual resources for.

RESTful Login Failure: Return 401 or Custom Response, First off. 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  Now after submitting that form with incorrect login data, the request is again met with a 401 response (after an X number of failed logins this might be turned into a 403 by a plugin like Limit Login Attempts) presenting the form again. After submitting with correct login data, the request is met with a 200 OK

401 should be sent only when the request needs authorization header field and authorization fails. Since the Login API doesn't require authorization, hence 401 is the wrong error code in my opinion

As per the standard here https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

*10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].*

HTTP Response Status Codes – REST API Tutorial, The origin server MUST create the resource before returning the 201 status code. A 401 error response indicates that the client tried to operate on a protected Authentication will not help, and the request SHOULD NOT be repeated. /403-​forbidden-vs-401-unauthorized-http-responses/14713094#14713094 for a great​  An example of implementing custom unauthorized response body in ASP.NET Core 2.1. This helps to return a JSON message in the body of 401 response. Solution is a custom implementation of AuthorizeFilter attribute.

Return 409 with a proper error message.

401 Unauthorized, 401 Unauthorized client error status response code indicates that the request has not been applied because it lacks valid authentication  But my problem is that I would like to return a custom JSON when a user tried to login after he failed, something like this: {"errorCode":999,"Message":"User cannot login before x seconds"} where "x" is the value inside my Map. But I cannot figure how I can retrieve the username (to be able to fetch it in my Map) on login failure!

REST API Error Handling Best Practices, REST APIs use the Status-Line part of an HTTP response message to inform In all the calls, the server and the endpoint at the client both return a call A 401 error response indicates that the client tried to operate on a  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more Customize authentication failure response in Spring Security using AuthenticationFailureHandler

Authentication Error Format > RESTful APIs in the Real World , The response status code should be 401 and remember we're always returning that API problem format that has a detail property on it. And here, we can say  Now, let's see how we can handle the most common client errors – basically scenarios of a client sent an invalid request to the API: BindException: This exception is thrown when fatal binding errors occur.

401 Unauthorized Error: What It Is and How to Fix It, A detailed explanation of what a 401 Unauthorized Error response is, including resource is restricted and requires authentication, but the client failed to the 401 Unauthorized Error , and returning it as the HTTP response code to Plus, Airbrake makes it easy to customize exception parameters, while  The 204 status code is usually sent out in response to a PUT, POST, or DELETE request when the REST API declines to send back any status message or representation in the response message’s body. An API may also send 204 in conjunction with a GET request to indicate that the requested resource exists, but has no state representation to include in the body.

Comments
  • Your point about returning resources seems valid and maybe that's the right move here. As for stating that 401 is the proper response, I'd appreciate some explanation there. I've read the HTTP spec, as you have included here, but that to me does not read as a direct and obvious confirmation of your assertion. Namely, authentication is NOT required to ask about the validity of credentials - yet what you included says "specifically for use when authentication is required."
  • Your way of looking at it is correct. You don't need to be authenticated to be able to ask for your Account object. But you need to successfully authenticate to be able to receive the resource, and thats where authentication is required and has failed or has not yet been provided applies, since you don't ask for the validity of credentials, but for a specific resource based on the credentials you supply.
  • I understand why you want to do a "check-call" and for that, I would still promote 401 as the appropriate response code for a failed authentication, even if the call does not require authentication to to be callable. A 204 No Content might also be suitable, but feels a bit ambiguously.
  • I don't see how this can be correct, unless you are using Basic or Digest authentication. Per the quoted part of the spec: "The response must include a WWW-Authenticate" -- and if you refer to section 14.47: "The HTTP access authentication process is described in "HTTP Authentication: Basic and Digest Access Authentication". This implies to me that 401 is not appropriate if you are using typical email/password validation.
  • I think this may be wrong, I have been implementing clients both web and mobile and I intercept 401 to redirect to login screen. But when someone is already on the login screen and submits wrong credentials, the response also has 401 and will try to redirect again. There should be a different status code for failed attempt to get authenticated when trying explicitly. Maybe a bad request or even server error?
  • I agree with you on this, but what is the alternative response status to send? I have been implementing clients both web and mobile and I intercept 401 to redirect to login screen. But when someone is already on the login screen and submits wrong credentials, the response also has 401 and will try to redirect again... what would you do?