Reputation: 42758
After creating a basic REST service, I've have come to the point where it would be appropriate to add some sort of password protection, as I need to verify that my users are both properly logged and have sufficient permissions to execute whatever action they are going to.
The REST service will mainly be accessed from a Javascript-heavy frontend and with that in mind, I have come up with the two following alternatives to solve this:
Make users login by first sending credentials to a /login
page with POST
. The page sets a session cookie wherein the user is
marked as logged in, along with the permission level. On each
following request, I verify that the user is logged in and his/her
permission level. When the session expires, automatically or
manually (logout, the user will have to re-logon).
Temporarily save the credentials hashed locally and send the users credentials along every single request made by the user to verify the credentials & permissions backend on a per-request basis.
Are there more ways to solve this and is there something else that I should be concerned with?
Upvotes: 14
Views: 15720
Reputation: 26129
Make users login by first sending credentials to a /login page with POST. The page sets a session cookie wherein the user is marked as logged in, along with the permission level. On each following request, I verify that the user is logged in and his/her permission level. When the session expires, automatically or manually (logout, the user will have to re-logon).
Temporarily save the credentials hashed locally and send the users credentials along every single request made by the user to verify the credentials & permissions backend on a per-request basis.
Your first approach does not meat the statelessness constraint of REST. You cannot maintain client sessions on server side. This constraint makes REST highly scalable...
Your second solution is appropriate. The simplest way to use HTTP basic auth. You don't have to hash the password on client side. What you need is an encrypted connection. On server side you can have an [username, password] -> [identity, permissions]
cache, so this solution is much faster and superior in every other way than having server side sessions.
By 3rd party (non-trusted) clients the authentication is more complex, I guess you don't need that part.
Upvotes: 1
Reputation: 63797
I'm currently developing a REST API along with a client (written in javascript), below I'll try to explain the methods used to protect the API against unauthorized access.
Make your REST API to require a Auth-Key
header upon every request to the API, besides /api/authenticate
.
/api/authenticate
will take a username and a password (sent using POST
), and return user information along side with the Auth-Key
.
This Auth-Key
is randomly generated after a call to /api/authenticate
and stored in the backend users
table with the specific user entry, a md5
hash of the remote ip + the user agent provided by the client.
On every request the value of Auth-Key
, and the md5
sum mentioned, is searched for in users
. If a valid user is found that has been active during the past N
minutes the user will be granted access, if not: http return code 401.
In the REST client, first get the Auth-Key
by posting to /api/authenticate
, then store this value in a variable and send in on every future request.
Upvotes: 19
Reputation: 49104
First decide what it is that you're protecting against:
I recommend that you provide hashed keys for your service. That way you can manage the key issue separately from the services. Or a client key and a secret, Amazon does this.
It is always easier for the client if you have a stateless protocol. And send everything through the parameters, cookies are a bother for the client too.
Remember that it is in your interest to make it as easy as possible for potential developers to use your service. A super secure service that no one uses is boring.
You can let clients choose the security level by giving them the choice of HTTP or SSL/HTTP endpoints to connect to. Client choice is a good thing.
Upvotes: 2
Reputation: 1487
I'm no security-expert. I use the RESTful Play!-webframework and they do the following things to authenticate users.
If you want to protect the cookie against hijacking using https.
Upvotes: 0
Reputation: 7119
If you want to stay true to the definition of a REST service then it should be stateless and not store any login (or other context specific) data on the server: http://en.wikipedia.org/wiki/Representational_state_transfer#Constraints
Your 2nd approach would fit this model
Upvotes: 3