Question

I have a standard HTML login page, which I would much rather use than the standard HTTP authentication pop-up provided by browsers. Today, I am using session cookies to keep track of the session after logging in, but I'd like to be stateless and pass the HTTP authentication every time. The web services I am hitting already support this, so this is a browser-only issue.

Adding authentication credentials is trivial in jQuery, but I don't know how to keep them around. If you go from the login page (a jsp) to the Home page (another jsp) you clearly don't keep the username and password fields from the login page. I know some browsers will store your HTTP authentication credentials if you enter them from the pop-up, but I don't know if they get stored when using an XHRRequest. If they do, is there much consistency among browsers?

Also, the user needs to be able to "sign out" of the application, too. If the browser stores the authentication credentials, is there a way to clear them using JavaScript.

I feel like I can't be the first person to try to solve this. Is there some jQuery plugin or something that already handles this? Or is it simply not possible to do what I'm trying to do?

Was it helpful?

Solution 4

Update

The answer below was posted in 2012 and the links are mostly dead. However, since then, a more elegant standards-based approach to the same solution appeared using JSON Web Tokens. Here is a good blog post explaining how to use them.


Most answers miss the point, which is to avoid having any server-side session. I don't want any application state in the server. I'll award the bounty to answer that came closest, but the real credit goes to the rest-discuss group and Jon Moore for the correct answer and to Mike Amundsen for helping me to actually understand it.

The best answer I've gotten is to use a cookie, but not the typical automatic session id cookie given to you by most application servers. The cookie (which will automatically be sent with each subsequent request) is a user identifier and time signed by the server. You can include an expiration time with the cookie so it simulates the typical 30 minute session on a server (which means you have to push it forward with subsequent requests) as well as keeps the same cookie from being valid forever.

The XHR/AJAX part is a red herring. This will work whether you are doing XHR requests or an old-fashioned page-by-page web application. The main points are:

  • The cookie is automatically sent on subsequent requests so there's no special scripting required - it's just how browsers work already.
  • The server does not need to store any session for the user, so the user can hit any server in a cluster and not have to re-authenticate.

OTHER TIPS

You have 2 options:

1) Client-side storage of credentials -- not a good idea. For obvious reasons you don't want to store the username/password on the client. If you had a hashed version of the password, it might not be so bad, but still not recommended. In any case, if you're going to store on the client side, you either have to use a cookie, or HTML5 local storage (which is not widely supported, yet)

2) Server-side storage of credentials -- typically done with sessions. Then the resultant Session ID can be passed back to the client and persisted in either a cookie or in the URL of each subsequent AJAX call (?SESSID=xyz for example)

The server-side approach would be the most secure, reliable, and easiest to implement

Okay, I'll take a stab at helping ...

Firstly, understand how HTTP authentication works. There are two versions - Basic and Digest. Basic transmits in plaintext, digest is encrypted. With these types of authentication, the username/password are passed in the HTTP header with every single request. The browser captures these at login and they are stored in an inaccessible browser session cookie which is deleted when the browser session is closed. So, in answer to one of your questions, you can't access these from javascript.

You could create your own session cookie variables for username and password. The jQuery functions for this are really simple. See jquery-cookie module as one example of how to set session cookies. These could be retrieved from the session cookie and sent with each ajax request and validated in the server. However, this is not a particulary good way to do authentication since sniffing the network will allow anybody to easily grab your auth details. But, it would work.

Using session cookie based authentication where the session ID is sent sent with each request is the best way to do this. At the server side, you need to have a function called for every HTTP request. This function should do the following:

   check to see if the session has been authenticated
   if no:
       redirect to login screen
   if yes:
       do authorization and allow the user access to the page

Most web frameworks support session cookie authentication and the management of session ids at the server. This is definately the way to go.

This is interesting one.

Manage user sessions on server by use of cookies. Create a session when user first accesses the login page and pass the session id/key as value to one of the cookie via response. When the user is authenticated put user "key" info in cookie and "values" in application context at server. Once user is logged, any subsequent request will be authenticated based on session cookie value at server. Authorization will be done based on user "key" passed as cookie value.

On logout clear the session based cookies from server and refresh the site to default page.

Cookies are bizarre with different browsers - just a note ;)

Hope this helps.

Slightly interesting in that you consider pushing some of the authent to the client. If you want a conventional solution, KOGI's server-side suggestion is the way to go.

But you also seem to be asking questions about memory leaks involving your user supplied secrets. Good questions. But to take a general stab at answering that I'd say it would have to be browser specific. It's browser internals, javascript engine internals -dependent where a client side application (i.e., the browser, or js in the browser) is storing the values the user inputs.

Most likely those values are not replicated needlessly throughout memory, but there's no way to guarantee that. Apart from responsible javascript coding practices, there's nothing you can do to guarantee the limit of locations of user inputs.

Slight digression

The basic point is if you store it on the client it is not really secure -- unless, the serve stores encrypted information on the client with a key that only the server (or the user via their correct credentials), has. So you could conceivably code a JS application to do some authent on the client -- much the same as how bank card (used to?) do POS authent by checking the PIN to the PIN on the card, and not back at the DB. It's based on the (somewhat flimsy) assumption the user has no direct read/write access of the "dark area" cookie/local storage on client / mag strip on bank card. So I would only advise this as disqualifier for false authents and not as a sole qualifier for the credentials.

Main point

If you do want to be stateless, just store user credentials in localstorage, or as a cookie but encrypt them with a server key. When you need them send an XHR with the encrypted / use stored credentials to the server over HTTPS, let your server decrypt them and send them to the callback. Then pass those cleartext of HTTPS to do your authent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top