Reputation: 85
I would like to use an RESTfull Authentication API in my application. Imagine the following structure:
Create a new session token (Login):
POST /session/?username=&password <-- return session token
Use the token to update and get a protected ressource:
PUT /ressource/example?token={token}
GET /ressource/example?token={token}
Delete the token (Logout):
DELETE /session/{token}
Question: Is this API RESTfull? If no, how can I do it?
Upvotes: 2
Views: 3878
Reputation: 14581
Authentication and sessions are the area that is rarely truly RESTful, because they are stateful, unless you pass full authentication credentials with each request.
Here is what I do, similar to yours, with one big difference.
POST /session/ --> creates a session, passing credentials in HTTP Auth Header
The above returns a 201 if successful, along with the session ID, just like a real resource. It also includes a session token in the cookies (and in a special X-
type HTTP header), which can be used in each subsequent request.
GET /protectedResource --> includes the credential in the HTTP header
And to terminate/invalidate a session, which is a common activity, like clicking on "logout"
DELETE /session/sessionId
The only real difference from what you have done is that I would never pass the tokens and credentials in the query path or body. The only exception is if you want to do form-based authentication and submit, but even then, when I can, I prefer to process Web-side and submit as a header.
The reason is 2-fold:
One other advantage of HTTP auth (which is in the headers) is that it becomes immensely easier to test your REST API using curl:
curl --user username:pass http://server/protectedResource
And you can even generate session tokens and use them in curl.
If you are comfortable with nodejs, you can look at the README and source code for cansecurity http://github.com/deitch/cansecurity
Upvotes: 2
Reputation: 3065
Probably you should follow a slightly different approach to "get the user token" (or authentication token):
POST /authentication/{username} (with password in the HTTP header)
Or something similar, the idea is that the "resource" you want is the "token" or "authentication token" for a specific user. The POST you were using is not very "RESTful", since you are POSTing on the resource "session", so it would probably be the "details of a session"...
Concerning the PUT/GET, I think that seems to be "correct", i.e., you send your token in each request to make operations over the "resource".
Concerning the DELETE, I am not sure if that will ever take place... that probably is something you define in your server (web service) logic, e.g.: TTL for the token. I do not think the "client" side should be able to delete the token, but maybe you have some other requirement.
Just a last reminder, be very careful to use this in "plain text", i.e., always send this info (password and token) in the HTTP header over an encrypted channel (e.g.: HTTPS). Furthermore, there are several approaches (such as HTTP basic authentication) that already implement this type of authentication, you should take a look on them.
Upvotes: 0