Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
689 views
in Technique[技术] by (71.8m points)

web services - Securing REST API without reinventing the wheel

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:joepassword@example.com/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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't worry about being "RESTful", worry about security. Here's how I do it:

Step 1: User hits authentication service with credentials.

Step 2: If credentials check out, return a fingerprint, session id, etc..., and pop them into shared memory for quick retrieval later or use a database if you don't mind adding a few milliseconds to your web service turnaround time.

Step 3: Add an entry point call to the top of every web service script that validates the fingerprint and session id for every web service request.

Step 4: If the fingerprint and session id aren't valid or have timed out redirect to authentication.

READ THIS:

RESTful Authentication


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...