REST API - request to another account's record returns empty string or HTTP 404? - api

Should be to the request to resource in REST API that belongs to another account returned HTTP 404 status code or HTTP 200 with an empty string?

You may be looking for 403 Forbidden. This is for a case when the resource is present, but the (possibly) logged in user does not have permission to get.
The 404 Not Found should only be used if the resource is not present, meaning other permissions would not help.
200 OK should only be given if the request completed successfully, the client got a valid representation of the resource.

Agree with #Robert Bräutigam that HTTP 403 seems most appropriate.
However, consider a URL like:
/api/some-user-user-id/profile
If you return 403 for existing users and 404 for non-existent users - you could be enabling outsiders to discover user ids.
This may or may not be a problem.

Related

Is Basic Authorization always using the same "success condition"?

I have some code that looks at "Basic Authorization" requests from many different sites.
I want to know if I can make the following assumptions:
A successful response (credentials are correct) will always have response code 200 OK
A failed response (incorrect credentials) will always have response code 401 Unauthorized
Are the above fair assumptions, or is the success/fail conditions configurable per site?
No, there are other possible response codes.
According to the official spec, there can also be the error code 407.
Also, on MDN:
If a (proxy) server receives invalid credentials, it should respond with a 401 Unauthorized or with a 407 Proxy Authentication Required, and the user may send a new request or replace the Authorization header field.
If a (proxy) server receives valid credentials that are inadequate to access a given resource, the server should respond with the 403 Forbidden status code. Unlike 401 Unauthorized or 407 Proxy Authentication Required, authentication is impossible for this user and browsers will not propose a new attempt.
In all cases, the server may prefer returning a 404 Not Found status code, to hide the existence of the page to a user without adequate privileges or not correctly authenticated.
Besides that, I'm quite sure that an actual successful attempt will result in status code 200.

401 or 404, when trying to authorize a user

I have this argument with a co-worker while trying to authenticate a user with login API, what status code is best returned, 404 or 401, in a scenario the user doesn't exist, which still means the user is not authorized.
Are you doing a GET request on resource with a uri that identifies the user? 404 makes sense for this.
Are you doing a POST request on some /login endpoint, and the user doesn't exist? 401 might make more sense for this, 409 or 400 too, but I don't think 404 makes sense to me.
If it's a POST request to something called /login, and I do get a 404, this suggests to me that I have the endpoint wrong, it doesn't suggest to me that the information in the request body was wrong.

Why error login and password server return status 200 ok

All major web applications (Google, Facebook, etc.) return page status 200 ok in case of authentication failure, i.e. wrong login/password pair.
Although by definition, if a resource is not found with request URI - status 404 Not found is returned.
Wikipedia says:
[404 Not Found] Used when the requested resource is not found, whether it doesn't exist or if there was a 401 or 403 that, for security reasons, the service wants to mask
How does the login case differ?
Server code 200 means you get the response . Whether it is your wrong credentials or not. if Your request has not been processed then server returns different error code . But for your case,
Your login request has been processed , connection with database has been established and from that you get you wrong credential message . So code 200 is for your successfully processed request.

REST-API, proper HTTP status code for invalid DELETE

I'm designing a RESTful API that is using the HTTP status codes and verbs as key components in communicating.
On the religious level it's on the zealot side of RESTafarian.
Rule of thumb for deciding HTTP status codes has been this graph, or similar resources.
GET /api/documents/1 - 401 User has not logged in
GET /api/documents/1 - 200 User has permission
GET /api/documents/1 - 403 User does not have permission
DELETE /api/documents/1 - 204 Users has permission
DELETE /api/documents/1 - 403 User does not have permission
GET /api/documents/2 - 404 Users permission irrelevant, resource does not exist
DELETE /api/documents/2 - 404 Users permission irrelevant, resource does not exist
DELETE /api/documents/1 - 404 Users has permission, resource already deleted
DELETE /api/documents/1 - 404 Users does not have permission, resource already deleted
Goals:
Consistency in usage
Not to expose private information through errors
Proper use of status codes for client or middle layer caches
Fail early, keep lookups to a minimum
In this situation there is a lot of different status code to chose from ( 404, 403, 410, 405) and in my case I went with 403 on a existing resource if its not yours to not clear the cache, and 404 on all non existing resources so to tell the clients to wipe that data.
But I do not like the switch from 403 to 404 on resources that are not yours.
I'm interested to hear from others how you solved this use-case, or in general what status codes you feel appropriate to send in all invalid DELETE calls, since I deem that as one of the hardest to be concise with.
(A lot of REST discussions and answers on the internet in it whole are just "Throw a 400 bad request, no one cares anyway", I do not have a problem that needs a quick fix or a pragmatic hack. Thanks)
General pointer: In case a resource exists but a user is not authorized to perform operations on it, you should return 401 over 403:
401 Unauthorized
Similar to 403 Forbidden, but specifically for use
when authentication is required and has failed or has not yet been
provided.
and
403 Forbidden
The request was a valid request, but the server is refusing to respond to it. Unlike a 401 Unauthorized response, authenticating will make no difference.
See also Correct HTTP status code when resource is available but not accessible because of permissions
I went with 403 on a existing resource if its not yours to not clear
the cache, and 404 on all non existing resources so to tell the
clients to wipe that data.
As pointed out earlier, 401 should be used instead of 403. 404 is ok to return if you just want to say "sorry, resource not found". If you however want to say "resource was here but it's not anymore and never again will be" (this appears to be the case in your situation) you can return 410:
410 Gone
Indicates that the resource requested is no longer available
and will not be available again. This should be used when a
resource has been intentionally removed and the resource should be
purged. Upon receiving a 410 status code, the client should not
request the resource again in the future. Clients such as search
engines should remove the resource from their indices
To summarize, this is how I would implement it in your case. The changes I made are in bold.
GET /api/documents/1 - 401 User has not logged in
GET /api/documents/1 - 200 User has permission
GET /api/documents/1 - 401 User does not have permission
DELETE /api/documents/1 - 204 User has permission
DELETE /api/documents/1 - 403 User does not have permission
GET /api/documents/2 - 404 Users permission irrelevant, resource does not exist
DELETE /api/documents/2 - 404 Users permission irrelevant, resource does not exist
DELETE /api/documents/1 - 410 User has permission, resource already deleted
DELETE /api/documents/1 - 401 User does not have permission, resource already deleted
For the last one, you can return 401 if you do not want the unauthorized user to know that there was a resource that has already been deleted. If you don't care you can return 410. That is for you to decide.
I do not like the switch from 403 to 404 on resources that are not yours.
It's perfectly fine to return different status codes depending on what the situation is.
I hope this helps you out a bit.
The response code for an invalid delete call depends on what the failure is. In your cases, I would go with:
DELETE /api/documents/1 - Users has permission
204 No Content
DELETE /api/documents/2 - Users permission irrelevant, resource does not exist
404 Not Found
DELETE /api/documents/1 - Users has permission, resource already deleted
410 Gone
DELETE /api/documents/1 - Users does not have permission, resource already deleted
403 Forbidden
The last call is the only one worth really talking about. I believe (and your graph agrees) that the user's lack of permission takes precedence over the resource already being deleted. If the user were to get a 410, then you'd be leaking information (resource already deleted).
As far as 401/403, 401 is "you haven't logged in yet". 403 is "you have logged in, and you don't have permission to do what you want". I don't see anything unusual in your usage of those codes.
Having said all this, I feel like I'm somehow misinterpreting the question.
I don't like the idea of a 404 as representing a failed delete where the resource cannot be found (or for a put or patch for that matter). It is fairly common to have DNS issues and for people to have parameter based routing issues that would both yield a 404 if the actual site could not be found. Introducing this type of ambiguity can make diagnosing simple problems really and unnecessarily difficult. I think 410 Gone is a better choice for representing a resource not found when it comes to APIs.

What HTTP error codes should my API return if a 3rd party API auth fails?

I'm writing a REST-ish API service the provides the ability to interact with the end user's data in other 3rd party services (themselves REST APIs) via OAuth. A common example might be publishing data from my service to a third-party service such as Facebook or Twitter.
Suppose, for example, I perform an OAuth dance with the end user and Facebook, resulting in some short-term access token that my service can use to interact with the user's Facebook account. If that access token expires and the user attempts to use my service to publish to Facebook, what sort of error do I return to the user?
401 doesn't seem quite right to me; it seems that 401 would apply to the user's auth state with MY service. 403 seems much more appropriate, but also quite generic.
401 is the way to go. Two excerpts from the RFC2616 which defines the HTTP protocol:
Section 10.4.2 (about 401):
If the request already included Authorization credentials, then the 401
response indicates that authorization has been refused for those
credentials.
This seems to be appropriate for expired tokens. There are authentication credentials, but they're refused, so the user agent must re-authenticate.
Section 10.4.4 (about 403):
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
This should be used when the resource can't be accessed despite the user credentials. Could be a website/API that works only on US being hit by a asian IP or a webpage that has been declared harmful and was deactivated (so the content WAS found, but the server is denying serving it).
On OAuth2, the recommended workflow depends on how the token is being passed. If passed by the Authorization header, the server may return a 401. When passed via query string parameter, the most appropriate response is a 400 Bad Request (unfortunately, the most generic one HTTP has). This is defined by section 5.2 of the OAuth2 spec https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26
There's nothing wrong with being generic, and it sounds like a 403 status would be relevant - there is nothing stopping you from providing a more human readable version that elaborates in a bit more detail why.
I think the following is a comprehensive list if you have some level of ambition when it comes to error responses.
400 Bad Request
For requests that are malformed, for example if a parameter requires an int between 0-9 and 11 has been sent. You can return this, and in the response body specify parameter x requires a value between 0 and 9
401 Unauthorized
Used only for authorization issues. The signature may be wrong, the nonce may have been used before, the timestamp that was sent is not within an acceptable time window, again, use the response body to specify more exactly why you respond with this. For the sake of clarify use this only for OAuth related errors.
403 Forbidden
Expressly to signify that an operation that is well formed, and authorized, is not possible at all (either right now, or ever). Take for example if a resource has been locked for editing by another user: use the response body to say something along the lines of Another person is editing this right now, you'll have to wait mmkay?.
403 Forbidden can also have to do with trying to reach resources. Say for example that a user has access to a resource /resource/101212/properties.json but not to /resource/999/properties.json, then you can simply state: Forbidden due to access rights in the response body.
404 Not Found
The requested resource does not exist. Or the URL simply does not successfully map to an API in your service. Specify in response body.
405 Method Not Allowed
This is to represent that the API can not be called with for example GET but another method must be used. When this is returned also you MUST return the extra response header Allow: POST, PUT, etc.