Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User authentication in Knockout.js applications

(I was told on Twitter I am being too vague here so I will try and edit)

I'm just starting to use Knockout.js for an application with a PHP back-end (an API that spits out JSON results). Parts of the application will requires users to be authenticated to use them (it's an app for voting on who "won" a particular transaction in a fantasy baseball league)

I am wondering how people are handling doing authentication using server-side APIs and frameworks like Knockout. I can easily write PHP code that accepts credentials validates them, and returns a response I just don't know how to maintain that state that the user is 'authenticated' using Knockout.

Add to that the problem of maintaining that 'authenticated state' across more than one page, and I'm wondering how it would even be possible. In PHP you could store that stuff inside the session or even using cookies.

I've got lots of experience with PHP so I'm not worried about the API part of this little side project. I'm a beginner with Knockout.js (and halfway between beginner and intermediate with Javascript) so any tips on how I can accomplish this would be greatly appreciated.

like image 539
GrumpyCanuck Avatar asked Feb 17 '12 03:02

GrumpyCanuck


3 Answers

Don't store authenticated state. Work with response codes, as you would with any other API.

Ultimately the backend process (simplified to the extreme) would be something like this:

  1. A request is received from the front end / client
  2. Does this request require privileges
    1. No, goto 4
    2. Yes, goto 3
  3. Is the user identified
    1. No, respond with 401
    2. Yes, but has insufficient privileges, respond with 403
    3. Yes, goto 4
  4. Send response

On the front end / client:

  1. Send a request to the API
  2. Is the response HTTP 200
    1. Yes, goto 4
    2. No, goto 3
  3. Was it a 401
    1. Yes, display login screen
    2. No, trigger error
  4. Display results

This might not be the best UX design out there, if you all of a sudden are faced with a login screen out of the blue. This can be circumvented though, by allowing the user to authenticate at any point in time, but don't require it until absolutely necessary. (And for ultimate smoothness, you need to be able to replay the request which failed once the authentication succeeds.)

Of course, for subsequent requests this requires either that you have a session running on the server or that your transport layer can transparently append an OAuth token or similar to requests after authentication.

Essentially this is the same as storing the authenticated state, but is more transparent and does at no point assume that the state is what the flag says. Say, for example, that you use sessions which you store in a memcached, which segfaults and restarts. This means your sessions are gone and anyone who was authenticated is not anymore. If your front end still has the authenticated = true and relies on it, stuff will break.

UPDATE:

After sleeping on this overnight, I realize you must differentiate between 401 and 403. Since there may be users of different levels, you need 403 to tell the front end / client that even though this user may be authenticated he still isn't allowed access.

like image 193
nikc.org Avatar answered Oct 22 '22 21:10

nikc.org


You can store the authenticated state using a cookie, by sending a cookie in the response header of any authenticated request (i.e. login). The browser will hold on to that and send it in the headers of subsequent requests. No need to manage that manually in your app.

You'd need to design your Knockout.js models to handle failure responses from the API when not authorized, but you would be doing that anyway even without authentication.

(If you need to know in your app whether the user is logged in without performing an API request, you can check the cookie (manually in JS, or with a library like jquery-cookie)

like image 34
Clay Hinson Avatar answered Oct 22 '22 20:10

Clay Hinson


Storing the cookie is a great idea. Making it simple is the key.

like image 2
Mark Avatar answered Oct 22 '22 20:10

Mark