Reputation: 4295
I'm playing around with writing a stateless, REST based API that I plan to consume from a couple of different places, one of which will be a single-page Javascript webapp. The idea is basically to have a single API that is used from the various different clients - including ones that are potentially written by other people, but still potentially need access to user data - instead of having different APIs for different clients.
The problem I'm currently hitting up against is Authentication. Ideally I'd like to use something standard here instead of rolling my own, but I'm struggling to find something standard that actually fits. I'm also trying to avoid the solution of different authentication mechanisms depending on who is making the call. At this stage I don't actually need anything more than just authentication of the user that is actually using the application - via username and password, or similar - but if/when clients that aren't the web page want to use it they should probably be authenticated as well.
From what I've been looking at, it seems that the best way to do this is actually to just use HTTP Basic authentication over an HTTPS connection. I can't help but think that this is missing something though. The obvious alternatives seem to be OAuth 1.0 - which requires that the potentially insecure Javascript session knows the Client Secret - or OAuth 2.0 - which seems to go back to using the username/password over SSL to generate an access token, and then using that access token on future requests again over SSL, which is basically the same as HTTP Basic but obfuscated a bit.
Note that I've not counted HTTP Digest here, simply because - as I understand it - what's passed to the server is something that includes the password in a non-retrievable form (i.e. hashed), and if I store the password in the backend in a non-retrievable form as well then I can't compare the two...
Upvotes: 3
Views: 1979
Reputation: 5296
I would create a separate API for handling the user login. Your API client (a JS web page) can then submit the username/password via HTTP Digest + SSL to this login API. The API will then perform the login against a user store (a DB or a file etc.), and return the result - Approved/Denied Access.
If approved, it should return a authenticated token (like for instance, a one way hash function over username+password+roles+permissions+datetime or whatever).
All subsequent requests by your JS client (via the browser) will need to submit this token (which will be carried around in the user session object, in an encrypted cookie perhaps) to all APIs you are interacting with. The token can be timed to expire, after which the user will be forced to re-login.
This approach maintains stateless-ness, but has some issues. What if the login token gets stolen, or shared by the user? During the token's lifetime, anybody with a copy of token can fire away queries pretending to be your user (man-in-the-middle). SSL should prevent that being the outermost envelope for the messages.
I can imagine doing some sort of hand-shakes between your REST (business) APIs and REST (login) API. So when your REST business APIs receive this token, maybe it can ask the login API to verify if it created this and for what user agent.
Anyways, for simple applications, the above approach should suffice.
Upvotes: 1