For public rest APIs, kinda understand since it gives better info, but it is necessary ? People still need to read the doc anyways ...
For protected(auth required) rest APIs, just 200 or 404 to prevent leaking important server stats?
Ex: Say i have a API endpoint, and authentication failed or other measure cause the failure of auth, should i send 401 code or just say 404 (or any generic code) to refuse the request ?
Ex: Say i have a API endpoint, and authentication failed or other measure cause the failure of auth, should i send 401 code or just say 404 (or any generic code) to refuse the request ?
This is a very useful question, and for a private API the answer is 404. Give the caller nothing. Do not say "you were supposed to authenticate" or "your authentication was wrong" or "if you did something slightly differently, then this would have worked." For a private API, anyone connecting should know what is required. Anyone who doesn't should go away. Send then 404. Nobody is here. This is not an interesting endpoint. Stop scanning me.
For a public API, you want to help your caller as much as possible. Tell them the mistakes they've made and how they might fix the request to be acceptable. For a private API, give nothing.
Related
I'm implementing the logic for a RESTful web server which supports searching with a SolR like syntax. Here are some common valid requests:
"https://www.somewhere.com/fooResource/123"
"https://www.somewhere.com/fooResource/456"
"https://www.somewhere.com/fooResource?q=title:hi"
"https://www.somewhere.com/fooResource?q=title:hello&sort=foo"
My question is very generic; what should I do if I receive a request like this?
"https://www.somewhere.com/fooResource?q=title:hi&something=foo"
I received a query parameter "something" which has no meaning to me, and our search engine will ignore it. Should I
return a 4xx status code immediately
ignore it and return a 200 with results
either my be "right" depending on my use case
Many web pages just ignore stuff that they aren't expecting.
Usually the URL and parameters are a result of clicking something or running some code on a browser or web service client. These would seldom submit anything unexpected.
If there is some reason you expect someone to be fooling with your web site and submitting requests that are "hackish" in some fashion, you might want to lock them out by recognizing illegal parameters and returning some error. 4xx would be reasonable for REST service.
Read the HTTP status definitions. I would practice not returning anything with bad info. The definition of 400 is The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications. and seems appropriate here, but your use case may deem otherwise.
If you IGNORE you are not giving the client any information. They may never know something is wrong.
I have been trying to learn OAuth (1.0) and have been testing my code by trying to access my contacts on Google. This is easy because I don't have to set up a friend/consumer relationship (Google just allows anonymous/anonymous for the consumer token) and because Google has the OAuth Playground to help me along.
So I set my code up as follows to go to
Request Token: https://www.google.com/accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F
Authorized Request Token: https://www.google.com/accounts/OAuthAuthorizeToken
Access Token: https://www.google.com/accounts/OAuthGetAccessToken
Everything seemed to be going well - I got the request token alright, authorized it fine, and was able to get an access token. I then tried to make a request to https://www.google.com/m8/feeds/contacts/default/full/
Only problem was, I kept getting this error: "401: AuthSub token has wrong scope"
I was confused by this because when I made the same request with the same consumer information in the OAuth Playground ( http://googlecodesamples.com/oauth_playground/index.php ) everything would work out alright.
Eventually, I found the following question: HTTP/1.1 401 Token invalid - AuthSub token has wrong scope
The top answer led me to my solution - there was code in one of the JARs I was using that was written to always set the port to 443 for https or 80 for http. When I stepped through my code and changed the port to -1, my request worked out fine and I was able to get the information I wanted.
Unfortunately, I'm not able to change the code in the JAR file, so I'm going to have to fix things on my end. In the answer to that question, 'Jonathan' said:
Another workaround would be to include the :443 in the token scope; it just has to match
I tried changing my request token query string to ?scope=https%3A%2F%2Fwww.google.com **%3A443** %2Fm8%2Ffeeds%2F and Google just refused to give me a request token - it gave me a 400 error saying Invalid scope: https://www.google.com:443/m8/feeds/. Changing https to http didn't do anything. How would I do what Jonathan (who hasn't been online in almost a year) suggested?
The fact that Google's auth scopes are URLs is basically academic -- they aren't actually serving anything useful (see for yourself), so adding a port just confuses Google. So Jonathan was incorrect in his suggestion.
The only reason they even look like URLs is so that they could be expected to be universally unique (even this is only arguably true).
So don't put the :443 in your auth scope.
Say I have a website that allows anyone to log in through oauth or similar, but only allows certain uses to create or modify content. Should they somehow make a request for page for creating a new post, I'll do a check and redirect them if they don't have the appropriate permissions.
It is considered acceptable to redirect to the "403 Error" page in this situation? There was no actual HTTP response with a 403 status code, there was no database- or server- level query that was failed - just my business logic. Am I misappropriating the idea of HTTP status codes if I serve an error 403 page with a specific explanatory message?
You are free to do so, but I think if you want to expose an API you would use an actual 403 response because they carry meaning that will be nicely handled by the client.
If you want to display a page to the client and will be using redirect, you will lose this meaning of the "403".
Isn't it better to just redirect them to an explanation page without including the "403" code. Or better yet, redirect them to a more helpful place, like the sign up page if that is what they have to do to make a post, or back to the original page with a floating message.
We want to help the user get closer to their goals instead of confusing them with technical error codes.
There is often a lot of discussion about this very topic and it comes down to the following choices:
a 5xx? Of course not. This is not a server error.
a 400? Not really, it wasn't a malformed request.
a 401? Probably not, 401 is generally for authorization in general, not application-level permissions. If your user has already logged in but has the wrong role, and you want to let the user know, then use something else.
a 404? Perhaps, as the server can't find the resource for this particular user, but if you want to tell the user "well such a resource is available but you can't have it because you lack permissions" then go with something else.
a 403? Actually, this one makes a lot of sense. Here is the definition from the RFC
403 Forbidden The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
In your question you mention your intention to redirect the user. If you are making a RESTFUL web service then just return the 403. If you are doing an entire web app, you can control the 403 and redirect....
I use ASIHTTPRequest framework in my iPhone application to manage the HTTP communication. I followed their examples given in the project home page to send asynchronous requests. There we have to implement two callbacks, one for requestFinish and other for requestFailed.
However, 60% of the time requests sent by the iPhone ends up in the "requestFinish" callback method and gives a valid HTTP status code. But sometimes it goes to "requestFailed" callback and the status code become '0' which is confusing.
My investigations revealed that the internet connection is ok, and I am sending the request to the correct URL, however no log messages found in server log.
So why does the request gets dropped in the middle so randomly? Has anyone came across with this type of issue. Will be very helpful.
Thanks
Are you looking at the status code of the ASIHTTPRequest object? That code is simply an HTTP response code - if you didn't get a response, then that should be zero.
Instead, you want to look at the NSError object that the delegate failure callback gives you.
I would use something like:
NSLog(#"%#",[error localizedErrorDescription]);
To print out to the log what the error is. Of course, "error" is the name of the variable in the method signature - you should double-check that, I think that's what the default is.
In [ASHTTPRequest initialize], I changed
[sharedQueue setMaxConcurrentOperationCount:4]
to
[sharedQueue setMaxConcurrentOperationCount:10]
This work for me, but I don't know why.
MORE:
I found this.
As well as what phooze suggested, there is logging in ASIHTTPRequestConfig.h that you can enable, that may provide a clue as to what is happening.
I am building a RESTful protocol for Dynamic Carpooling applications, for my Computer Science thesis.
In the Protocol I also have to formally specify the HTTP status code for each operation. I've got this "privacy related" problem. Suppose the following:
GET /api/persons/angela/location
Retrieves the current position of user "angela".
It is obvious that not everybody should be able to obtain a result. Only angela itself and a possible driver that is going to pick her should be able to know it.
I can not decide whether to return a 404 Not Found or a 401 Forbidden here.
Any hints? What would be the best one and why?
According to Wikipedia (and RFC 2616), a 401 code is used when a page exists but requires authentication; 403 is for a page where authenticating won't change anything. (In the wild, 403 usually means the permissions on something are wrong, whereas a 401 will prompt the user for a username/password). 404 is for where the document simply doesn't exist.
In your case, it seems like 401 is the most appropriate code, since there is some way of authenticating the users who DO have access to the page.
If authorization credentials are provided in the request and the requester does not have permissions to access this resource then you should return 403.
If no authorization credentials are provided in the request then you should return 401.
Definitely NOT 404. 404 is just Not Found.
401 is access denied.
403 is forbidden.
I would go with 401
To me I will use 400 Bad request.
Because my application will not go unaccessable resources in programmatically.
Filtering users permission and hide unaccessable resources is good user experience in my opinion.
If my server got unaccessable request which means some person trying to do something.
That is why I choose 400 - Bad request in my applications.