As described in a previous question, we are in process of rebuilding a web service using two completely separated layers (servers and domains) for the frontend (HTML5 web app) and the backend (probably using Node.js).
The frontend will be served by a CDN over SSL, on the "www" subdomain (www.foo.com), while the backend will be an API server on the "api" subdomain. The API server will of course communicate over SSL and will only provide JSON-formatted data (with PJAX as an option we are evaluating).
We would like some feedback on our current design proposal.
Login
- User fills a form with username/password and submits it locally.
- The client computes the hash of the password locally (PBKDF2) and submits it to the server (e.g.
POST /login
with the fields username and hashed password) - The server checks the hash against the one in the database, and if successful will respond with a session key.
- The client stores the session key in its local storage (HTML5).
If the login is not successful, after 3 failed attempts a captcha will be required too.
We considered the use of OAuth for authorization, but because of technical reasons we need the client on the "www" subdomain to see the password in cleartext at least for a few seconds. (that's another story :) )
Session
- The session key is sent in clear text (on SSL) along with every request and is used by the API server to authenticate the user.
- Additionally, each request must contain a "seq" field (for example, timestamp in milliseconds) that has to be greater than the previous one used. If this doesn't happen, the session key is revoked.
- The session key expires after 30 minutes.
- Before expiration, the client may request a refresh.
- The server itself may refresh the session key after 10 minutes along with a response to a request. (e.g. in the response for the method
GET /something
there is a field "session key" which contains a replacement session key). - When the session key is refreshed, the old one is revoked instantaneously (or after 30 seconds - even if two concurrent requests are extremely rare in our application).
Additional security: both the web server (www) and the API server will only respond to requests over SSL. The web server redirects users not using SSL to the SSL version (using HSTS: the redirect will happen only once for each user, hopefully reducing the risks for man-in-the-middle attacks).
Do you think this design (if implemented correctly) provides good protection? Is there any other recommendation you think we should consider? Thank you.