When designing REST API is it common to authenticate a user first?
The typical use case I am looking for is:
- User wants to get data. Sure cool we like to share! Get a public API key and read away!
- User wants to store/update data... woah wait up! who are you, can you do this?
I would like to build it once and allow say a web-app, an android application or an iPhone application to use it.
A REST API appears to be a logical choice with requirements like this
To illustrate my question I'll use a simple example.
I have an item in a database, which has a rating attribute (integer 1 to 5).
If I understand REST correctly I would implement a GET request using the language of my choice that returns csv, xml or json like this:
http://example.com/product/getrating/{id}/
Say we pick JSON we return:
{
"id": "1",
"name": "widget1",
"attributes": { "rating": {"type":"int", "value":4} }
}
This is fine for public facing APIs. I get that part.
Where I have tons of question is how do I combine this with a security model? I'm used to web-app security where I have a session state identifying my user at all time so I can control what they can do no matter what they decide to send me. As I understand it this isn't RESTful so would be a bad solution in this case.
I'll try to use another example using the same item/rating.
If user "JOE" wants to add a rating to an item
This could be done using:
http://example.com/product/addrating/{id}/{givenRating}/
At this point I want to store the data saying that "JOE" gave product {id} a rating of {givenRating}.
Question: How do I know the request came from "JOE" and not "BOB".
Furthermore, what if it was for more sensible data like a user's phone number?
What I've got so far is:
1) Use the built-in feature of HTTP to authenticate at every request, either plain HTTP or HTTPS.
This means that every request now take the form of:
https://joe:[email protected]/product/addrating/{id}/{givenRating}/
2) Use an approach like Amazon's S3 with private and public key: http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
3) Use a cookie anyway and break the stateless part of REST.
The second approach appears better to me, but I am left wondering do I really have to re-invent this whole thing? Hashing, storing, generating the keys, etc all by myself?
This sounds a lot like using session in a typical web application and rewriting the entire stack yourself, which usually to me mean "You're doing it wrong" especially when dealing with security.
EDIT: I guess I should have mentioned OAuth as well.
See Question&Answers more detail:
os