How to store an auth token in an Angular app

The Zuidz picture The Zuidz · May 21, 2014 · Viewed 13.8k times · Source

I have an Angular application (SPA) that communicates with a REST API server and I'm interested in finding out the best method to store an access token that is returned from an API server so that the Angular client can use it to authenticate future requests to the API. For security reasons, I would like to store it as a browser session variable so that the token is not persisted after the browser is closed.

I'm implementing a slightly customized version of OAuth 2.0 using the Resource Owner Password grant. The Angular application provides a form for the user to enter their username and password. These credentials are then sent to the API in exchange for an access token which must then be sent as a header (Authorization: Bearer %Token%) for all outbound requests to the API so that it can authorize requests to other routes.

I'm fairly new to the realm of Angular, but the workflow I would like to implement as far as handling these tokens is summarized as follows.

1) The client makes a request to the API providing it with user credentials.

2) If this request is successful, the token is stored somewhere (where is the question)

3) Intercept HTTP requests. If token is set, pass it along as a header to API

4) Token is destroyed when the browser/tab is closed.

I know Angular offers $window.sessionStorage, which appears to be what I am looking for, but I am concerned by the potential for it not to work on all browsers according to various resources I've read. This is an enterprise grade application and must be compatible across a broad range of browsers (IE, Chrome, Firefox). Can I safely use this with the confidence that it will be stable?

The alternatives, from what I understand, are either $window.localStorage or cookies ($cookies, $cookieStore). This would not be an ideal solution for me since I don't want this data to persist, but if this is more reliable I'll have to sacrifice efficiency for compatibility. I was also thinking it might be possible to simply set it as a value on the $rootScope and reference it this way, but I'm not sure if this is feasible.

I hope that all made sense. Any help / suggestions would be greatly appreciated. Thanks!

Answer

Jono Hill picture Jono Hill · May 21, 2014

If you are looking for something that will definitely not persist then I would simply keep the token in memory and not rely on the browser for storage. However storing inside rootScope would not be best practice.

I would recommend that you wrap your server access code in an Angular Service if you have not done so already. You can then encapsulate your token within that Service at runtime (e.g. as a property) without worrying about having to access it when calling from other parts of your application.

Angular Services are singleton so your "server service" will be a global instance that can be accessed using normal dependency injection.