The ability to reply to discussions is limited to PRO members. Want to join in the discussion? Click here to subscribe now.

Auth Interceptor in Angular for JWT

Auth Interceptor in Angular for JWT

7:53
Adding JWT support to the client. Storing the token in local storage, then creating a http interceptor to add the token to requests made to the server. Also implementing logout.
Watch this lesson now
Avatar
egghead.io

Adding JWT support to the client. Storing the token in local storage, then creating a http interceptor to add the token to requests made to the server. Also implementing logout.

Avatar
Marek

may be little bit easier is use https://github.com/auth0/angular-jwt

Avatar
Toby

This is a little off-topic, but how are you getting all of the ng support within WebStorm? I noticed when you make you factories, it auto-completes much of the code for you. Is that something you did within WS? I'm using the Live Templates, but they behave the same way I'm seeing your stuff work.

Avatar
Kent C.

Hi Toby, I actually don't believe I've done anything to get the auto-complete. All I can say is make sure that you're on the latest version of WebStorm. If that's not it, I'd just google around...

In reply to Toby
Avatar
Kent C.

Seems like an awesome library :-) I don't think it was around at the time I made this lesson.

In reply to Marek
Avatar
Martin

From what I've read saving the token to local storage isn't the best solution, and instead it should be saved to a cookie (with SSL for production). Why is there a discrepancy in where different developers suggest storing the token?

Avatar
Kent C.

From a security standpoint, it doesn't make a difference. The reason I chose not to store it as a cookie is because cookies are commonly used as a means to share data between the client and the server during requests. However, with the "new" architecture of having the client app and the api being served on different domains, that data sharing doesn't happen (clients don't send cookies to servers under a different domain including sub domains). Therefore I believe it's misleading to use cookies and choose local or session storage instead.

In reply to Martin
Avatar
Martin

Thanks Kent, that makes a lot of sense. Cheers

In reply to Kent C.
Avatar
Martin

Hi Kent, sorry one more question. I've also read about using a refresh token (or single request token) that produces a single use token to reduce the window of attack if a token is compromised, as it's only valid for the single request. Is this something you consider in your applications? and from the current video how would this change the implementation. Seems like you could do it by adding a response to the interceptor that used the AuthTokenFactory. If knowing something about the application I'm working on helps I'm building an Ionic application with a Laravel 5.1 API.

In reply to Kent C.
Avatar
Kent C.

I don't think there's anything wrong with that. The interceptor hides the complexity away from the rest of your app so you don't need to think about it at all.

I've never done this before, but I'd be concerned about timing issues. Like, what if I send several requests at once and the server sends response A before response B, so response B's token is the one that needs to be used next, but then response B gets to the client first and response A's token overrides B's token. I'm not sure how likely that is to occur, and like I said I've never tried this kind of an architecture, but I'd be concerned about that.

Just as a tip. As far as I'm aware, most web applications are using cookies or localStorage with a token that lasts the duration of the logged in session. This is no less secure than cookies. In either case, if someone gets ahold of the machine, they can look right at the cookie/token and use it to make requests. What you've suggested would help alleviate that concern only if that individual weren't able to get the next valid token from your server, which is unlikely. So I don't really see what this approach buys you...

In reply to Martin
Avatar
Matheus

Hi Kent, thanks for the video it was awesome. About this topic I'm actually reading a lot to further understand the security discussion and from what I read I think that it still scares me a little bit using the localStorage because of possible XSS.

A malicious script (not necessary unsanitized from the end-user; it could be from a CDN compromised script) could get the JWT of a bunch of clients using this technique. Using an HTTP only SSL cookie would have the advantage of not allowing this kind of hijacking, however, now you have to worry about CSRF, and that sucks as well.

OWASP Top 10 list puts XSS before CSRF so I'm guessing this problem is harder to spot and mitigate the risks.

What is your opinion on that? I'm being completely honest with you in that I don't know what's the next step to take as I already have an Mobile App running on Windows Azure Mobile Services and now that we're implementing also a Web Client our team is having these kind of concerns.

Thanks a lot once again.

In reply to Kent C.
Avatar
Kent C.

I think, like with all technology, you have to make certain trade-offs. If you're concerned about a compromised script from a CDN hijacking your users and stealing tokens, then don't use a CDN you don't trust. You could potentially store the token in a cookie if you want to. But I'm not certain that you'd be able to access it.

In reply to Matheus
Avatar
marshallformula

Here's a great article with a run-down on the security trade-offs for either storage solution:

https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

In reply to Kent C.
Avatar
Juan

Any samples on how to create the cookie alternative?

In reply to marshallformula
Avatar
Juan

A video series explaining the two alternatives would be great (tokens in local storage VS cookies for storage)

In reply to Juan
Avatar
Kent C.

It's pretty much just a matter of changing the AuthTokenFactory to utilize the Cookie API rather than the LocalStorage API.

In reply to Juan
Avatar
Tony

Kent,

My project's code is split out such that the controllers are within different files as is the factory. This method has been working well for me... until I try to add the Auth Interceptor. I have a module('report') to which I am trying to add the interceptor. I have tried the below, but while I get no error, the function also doesn't get called.

My question is, how to I inject the code defined in the jwt.js file (below) into the module after the module has been defined in my app.js rather than lumping all the code into a huge jumbled js file.

angular.module('report')
.requires.push.apply(angular.module('report'), ['$httpProvider', function($httpProvider) {

$httpProvider.interceptors.push('AuthInterceptor');
}]);

The jwt.js file:

(function () {

angular
    .module('report')
    .factory('AuthInterceptor', function (API, auth) {
        return {
            // automatically attach Authorization header
            request: addToken
        };
        function addToken (config) {
            var token = jwt.getToken();

            if (token) {
                config.headers = config.headers || {};
                config.headers.Authorization = 'Bearer ' + token;
            }
            return config;
        }
    })
    .factory('jwt', function ($window, $q) {
        var store = $window.localStorage,
            key = 'auth-token',
            dev = $q.defer();

        return {
            setToken: setToken,
            getToken: getToken
        };

        function setToken (token) {
            if (token) {
                store.setItem(key, token);
            } else {
                store.removeItem(key);
            }
        }

        function getToken () {
            return store.getItem(key);
        }
    });

})();

In reply to Kent C.
Avatar
Cary

In the video you say we usually hide the secret key in some where backend to keep it private,can you show me what to do to achieve that?

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?