Coder Social home page Coder Social logo

angular-jwt's Introduction

Warning This repository has been archived, the libaray has been deprecated, but remains available on NPM.

angular-jwt

FOSSA Status

This library will help you work with JWTs.

Sponsor

auth0 logo If you want to quickly add secure token-based authentication to your Angular projects, feel free to check Auth0's Angular SDK and free plan at auth0.com/developers

Key Features

  • Decode a JWT from your AngularJS app
  • Check the expiration date of the JWT
  • Automatically send the JWT in every request made to the server
  • Manage the user's authentication state with authManager

Installing it

You have several options: Install with either bower or npm and link to the installed file from html using script tag.

bower install angular-jwt
npm install angular-jwt

jwtHelper

jwtHelper will take care of helping you decode the token and check its expiration date.

Decoding the Token

angular
  .module('app', ['angular-jwt'])
  .controller('Controller', function Controller(jwtHelper) {
    var expToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NhbXBsZXMuYXV0aDAuY29tLyIsInN1YiI6ImZhY2Vib29rfDEwMTU0Mjg3MDI3NTEwMzAyIiwiYXVkIjoiQlVJSlNXOXg2MHNJSEJ3OEtkOUVtQ2JqOGVESUZ4REMiLCJleHAiOjE0MTIyMzQ3MzAsImlhdCI6MTQxMjE5ODczMH0.7M5sAV50fF1-_h9qVbdSgqAnXVF7mz3I6RjS6JiH0H8';  

    var tokenPayload = jwtHelper.decodeToken(expToken);
  });

Getting the Token Expiration Date

angular
  .module('app', ['angular-jwt'])
  .controller('Controller', function Controller(jwtHelper) {
    var date = jwtHelper.getTokenExpirationDate(expToken);
  });

Checking if the Token is Expired

angular
  .module('app', ['angular-jwt'])
  .controller('Controller', function Controller(jwtHelper) {
    var bool = jwtHelper.isTokenExpired(expToken);
  });

More Examples

You can see some more examples of how this works in the tests

jwtInterceptor

JWT interceptor will take care of sending the JWT in every request.

Basic Usage

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    // Please note we're annotating the function so that the $injector works when the file is minified
    jwtOptionsProvider.config({
      tokenGetter: ['myService', function(myService) {
        myService.doSomething();
        return localStorage.getItem('id_token');
      }]
    });

    $httpProvider.interceptors.push('jwtInterceptor');
  })
  .controller('Controller', function Controller($http) {
    // If localStorage contains the id_token it will be sent in the request
    // Authorization: Bearer [yourToken] will be sent
    $http({
      url: '/hola',
      method: 'GET'
    });
  });

Configuring the Authentication Scheme

By default, angular-jwt uses the Bearer scheme when sending JSON Web Tokens as an Authorization header. The header that gets attached to $http requests looks like this:

Authorization: Bearer eyJ0eXAiOiJKV...

If you would like to provide your own scheme, you can configure it by setting a value for authPrefix in the jwtOptionsProvider configuration.

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({
      authPrefix: 'MyPrefix '
      ...
    });

    $httpProvider.interceptors.push('jwtInterceptor');

Not Sending the JWT for Specific Requests

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    // Please note we're annotating the function so that the $injector works when the file is minified
    jwtOptionsProvider.config({
      tokenGetter: ['myService', function(myService) {
        myService.doSomething();
        return localStorage.getItem('id_token');
      }]
    });

    $httpProvider.interceptors.push('jwtInterceptor');
  })
  .controller('Controller', function Controller($http) {
    // This request will NOT send the token as it has skipAuthorization
    $http({
      url: '/hola',
      skipAuthorization: true,
      method: 'GET'
    });
  });

Whitelisting Domains

If you are calling an API that is on a domain other than your application's origin, you will need to whitelist it.

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({

      ...

      whiteListedDomains: ['api.myapp.com', 'localhost']
    });
  });

Note that you only need to provide the domain. Protocols (ex: http://) and port numbers should be omitted.

You can also specify the domain using a regular expression.

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({

      ...

      whiteListedDomains: [/^api-version-\d+\.myapp\.com$/i, 'localhost']
    });
  });

Regular expressions should be as strict as possible to prevent attackers from registering their own malicious domains to bypass the whitelist.

Not Sending the JWT for Template Requests

The tokenGetter method can have a parameter options injected by angular-jwt. This parameter is the options object of the current request.

By default the interceptor will send the JWT for all HTTP requests. This includes any ng-include directives or templateUrls defined in a state in the stateProvider. If you want to avoid sending the JWT for these requests you should adapt your tokenGetter method to fit your needs. For example:

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({
      tokenGetter: ['options', function(options) {
        // Skip authentication for any requests ending in .html
        if (options.url.substr(options.url.length - 5) == '.html') {
          return null;
        }

        return localStorage.getItem('id_token');
      }]
    });

    $httpProvider.interceptors.push('jwtInterceptor');
  });

Sending Different Tokens Based on URLs

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({
      tokenGetter: ['options', function(options) {
        if (options.url.indexOf('http://auth0.com') === 0) {
          return localStorage.getItem('auth0.id_token');
        } else {
          return localStorage.getItem('id_token');
        }
      }]
    });
    $httpProvider.interceptors.push('jwtInterceptor');
  })
  .controller('Controller', function Controller($http) {
    // This request will send the auth0.id_token since URL matches
    $http({
      url: 'http://auth0.com/hola',
      skipAuthorization: true,
      method: 'GET'
    });
  });

Managing Authentication state with authManager

Almost all applications that implement authentication need some indication of whether the user is authenticated or not and the authManager service provides a way to do this. Typical cases include conditionally showing and hiding different parts of the UI, checking whether the user is authenticated when the page is refreshed, and restricting routes to authenticated users.

  <button ng-if="!isAuthenticated">Log In</button>
  <button ng-if="isAuthenticated">Log Out</button>

Note: authManager set isAuthenticated on your $rootScope object, If you are using component-based architecture, your component $scope is isolated scope, it does not inherits $rootScope properties, you need to access $rootScope from component's template:

  <button ng-if="!$root.isAuthenticated">Log In</button>
  <button ng-if="$root.isAuthenticated">Log Out</button>

Getting Authentication State on Page Refresh

The authentication state that is set after login will only be good as long as the user doesn't refresh their page. If the page is refreshed, or the browser closed and reopened, the state will be lost. To check whether the user is actually authenticated when the page is refreshed, use the checkAuthOnRefresh method in the application's run block.

angular
  .module('app')
  .run(function(authManager) {

    authManager.checkAuthOnRefresh();

  });

Note: If your tokenGetter relies on request options, be mindful that checkAuthOnRefresh() will pass null as options since the call happens in the run phase of the Angular lifecycle and no requests are fired through the Angular app. If you are using requestion options, check that options isn't null in your tokenGetter function:

...

tokenGetter: ['options', function (options) {
  if (options && options.url.substr(options.url.length - 5) == '.html') {
    return null;
  }
  return localStorage.getItem('id_token');
}],

...

Responding to an Expired Token on Page Refresh

If the user is holding an expired JWT when the page is refreshed, the action that is taken is at your discretion. You may use the tokenHasExpired event to listen for expired tokens on page refresh and respond however you like.

// app.run.js

...

$rootScope.$on('tokenHasExpired', function() {
  alert('Your session has expired!');
});

Limiting Access to Routes

Access to various client-side routes can be limited to users who have an unexpired JWT, which is an indication that they are authenticated. Use requiresLogin: true on whichever routes you want to protect.

...

.state('ping', {
  url: '/ping',
  controller: 'PingController',
  templateUrl: 'components/ping/ping.html',
  controllerAs: 'vm',
  data: {
    requiresLogin: true
  }
});

...

Note: Protecting a route on the client side offers no guarantee that a savvy user won't be able to hack their way to that route. In fact, this could be done simply if the user alters the expiry time in their JWT with a tool like jwt.io. Always ensure that sensitive data is kept off the client side and is protected on the server.

Redirecting the User On Unauthorized Requests

When the user's JWT expires and they attempt a call to a secured endpoint, a 401 - Unauthorized response will be returned. In these cases you will likely want to redirect the user back to the page/state used for authentication so they can log in again. This can be done with the redirectWhenUnauthenticated method in the application's run block.

angular
  .module('app')
  .run(function(authManager) {

    ...

    authManager.redirectWhenUnauthenticated();

  });

Configuring the Login State

The page/state to send the user to when they are redirected because of an unauthorized request can be configured with jwtOptionsProvider.

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({
      unauthenticatedRedirectPath: '/login'
    });
  });

Configuring the Unauthenticated Redirector

If you would like to control the behavior of the redirection that happens when users become unauthenticated, you can configure jwtOptionsProvider with a custom function.

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    jwtOptionsProvider.config({
      unauthenticatedRedirector: ['$state', function($state) {
        $state.go('app.login');
      }]
    });
  });

Sending the token as a URL Param

angular.module('app', ['angular-jwt'])
.config(function Config($httpProvider, jwtOptionsProvider) {
  jwtOptionsProvider.config({
    urlParam: 'access_token',
    tokenGetter: ['myService', function(myService) {
      myService.doSomething();
      return localStorage.getItem('id_token');
    }]
  });

  $httpProvider.interceptors.push('jwtInterceptor');
})
.controller('Controller', function Controller($http) {
  // If localStorage contains the id_token it will be sent in the request
  // url will contain access_token=[yourToken]
  $http({
    url: '/hola',
    method: 'GET'
  });
})

More examples

You can see some more examples of how this works in the tests

FAQ

I have minification problems with angular-jwt in production. What's going on?

When you're using the tokenGetter function, it's then called with the injector. ngAnnotate doesn't automatically detect that this function receives services as parameters, therefore you must either annotate this method for ngAnnotate to know, or use it like follows:

jwtOptionsProvider({
  tokenGetter: ['store', '$http', function(store, $http) {
    ...
  }]
});

Usages

This library is used in auth0-angular and angular-lock.

Contributing

Just clone the repo, run npm install, bower install and then gulp to work :).

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

What is Auth0?

Auth0 helps you to:

  • Add authentication with multiple authentication sources, either social like Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others, or enterprise identity systems like Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider.
  • Add authentication through more traditional username/password databases.
  • Add support for linking different user accounts with the same user.
  • Support for generating signed Json Web Tokens to call your APIs and flow the user identity securely.
  • Analytics of how, when and where users are logging in.
  • Pull data from other sources and add it to the user profile, through JavaScript rules.

Create a free account in Auth0

  1. Go to Auth0 and click Sign Up.
  2. Use Google, GitHub or Microsoft Account to login.

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.

FOSSA Status

angular-jwt's People

Contributors

anongit avatar anthu avatar capesean avatar chenkie avatar chieffancypants avatar christopherthielen avatar damieng avatar doshprompt avatar douglaszaltron avatar emmanueldemey avatar fossabot avatar fvilers avatar itsananderson avatar jhkuperus avatar joshcanhelp avatar kaushikgandhi avatar kmaida avatar kylemantesso avatar laitine avatar lbalmaceda avatar lopsided avatar luisrudge avatar mgonto avatar nkpz avatar patrickjs avatar sambego avatar sildur avatar suvjunmd avatar valepu avatar zhuangya avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

ygrene

angular-jwt's Issues

can't decode token from jsonwebtoken on node

Hello , a few day I use angular-jwt to decode token from backend (nodejs) ,When I decede is working ok , but today angular-jwt can't decode I get result as "Object {_bsontype: "ObjectID", id: "V�uÔy�±Õ��#�", iat: 1452054188}" , So result must have object that I get from backend like a few day, How do I fix this issues

my token is a "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfYnNvbnR5cGUiOiJPYmplY3RJRCIsImlkIjoiVsKLdcOUecKWwrHDlVx1MDAxOMKSI8KBIiwiaWF0IjoxNDUyMDU0MTg4fQ.BWa6oha9nkx4WPxC5l_K-tya65aovAEgXY0tVvAuaEg"

ps. I have us mean.io to build my application
Thank.

The default unauthenticatedRedirector doesn't work

I'm working through some of the quickstart samples, and using the default unauthenticatedRedirector doesn't work.

My config:

    // Configuration for angular-jwt
    jwtOptionsProvider.config({
      tokenGetter: function() {
        return localStorage.getItem('id_token');
      },
      whiteListedDomains: ['localhost'],
      loginPath: '/login',
      unauthenticatedRedirectPath: '/login'
    });

The default redirector (https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwtOptions.js#L19):

      var options = {
        urlParam: null,
        authHeader: 'Authorization',
        authPrefix: 'Bearer ',
        whiteListedDomains: [],
        tokenGetter: function() {
          return null;
        },
        loginPath: '/',
        unauthenticatedRedirectPath: '/',
        unauthenticatedRedirector: function(location) {
          location.path(this.unauthenticatedRedirectPath);
        }
      }

It's not redirecting, because this is window, not the options object. The redirector is called here:

      function redirectWhenUnauthenticated() {
        $rootScope.$on('unauthenticated', function() {
          var redirector = config.unauthenticatedRedirector;
          var redirectFn;
          if(Array.isArray(redirector)) {
            redirectFn = redirector[redirector.length - 1];
            redirectFn($location);
            unauthenticate();
          } else {
            redirector($location);
          }
        });
      }

I will try working around the issue by supplying my own redirector function.

jwtInterceptor failed to include authorization header for $resource.

Hi,

I have configure the jwtHelper as per the documentation such as

// Please note we're annotating the function so that the $injector works when the file is minified
        jwtInterceptorProvider.tokenGetter = [ '$rootScope', '$http', 'jwtHelper', 'localStorageService', 'restEndPoint', function($rootScope, $http, jwtHelper, localStorageService, restEndPoint) {
            var idToken = localStorageService.get('token');
            if (idToken && jwtHelper.isTokenExpired(idToken)) {
              // This is a promise of a JWT id_token

              localStorageService.remove('token');

              return $http({
                url: restEndPoint + '/auth/api-token-refresh/',
                // This makes it so that this request doesn't send the JWT
                skipAuthorization: true,
                method: 'POST',
                data: {
                    token: idToken
                }
              }).then(function(response) {
                localStorageService.set('token', response.token);
                return response.token;
              });
            } else if (idToken){
                $rootScope.user = jwtHelper.decodeToken(idToken);
            } else {
              return idToken;
            }
        }];

        $httpProvider.interceptors.push('jwtInterceptor');

But unable to get authorization header while doing post request using $resource such as

angular.module('myApp')
  .factory('myFactory', ['$resource', 'restEndPoint', function ($resource, restEndPoint) {
    // Service logic
    // ...
    return $resource(restEndPoint+'/bids/:id')
}]);

In controller

$scope.data = new myFactory();
$scope.data.field1 = "xyz"
$scope.data.field2 = "xyz"

// This is where it calls a post request.
$scope.data.$save()

Below is the attached screen shot of request parameters.

screen shot 2015-12-29 at 11 40 10 am

Please let me know whether I missed anything related to $resource.

Thanks

Angular-jwt with angularjs 1.3

I see in the bower.json of the angular-jwt that
"angular": "~1.2.21"

is there any problem using angular-jwt with angularjs 1.3X ?

thanks

Incorrect dependency in package.json

In the package.json file, the karma-mocha-reporter is not listed as a development dependency. As a result, installing angular-jwt will also install karma-mocha-reporter.

Refreshed JWT not available

Hi. Is this case possible :

  • JWT is refreshed as explained
  • However, API takes time to send the refreshed token
  • Due to async behavior and promise, another API call is made on a business resource but refreshed token is not yet available. Authorization header is defined with the expired token.
  • A not authorized response is returned because used token is expired
  • Refreshed token is finally returned ... too late

How to handle such a case ? Is there something to change in the example or in the bundle source code ?

How to skipAuthorization for ng-include or stateProvider template requests?

I noticed my app is trying to get a token when using the ng-include directive or using the templateUrl in stateProvider. Eg:

<ng-include src="'app/header/header.html'"></ng-include>

or

$stateProvider
    .state('home', {
                url: '/',
                controller: 'HomeCtrl',
                controllerAs: 'home',
                templateUrl: 'app/home/home.html'
            })

I can't see any way to skip the authorization for these requests, I'm probably not looking in the right place. Can anyone help?

Thanks

FEATURE: JWT signature verification

Is there a good reason why JWT signature verification is not part of the library? If I got it correct, in essence you should not trust any JWT before the signature has been verified. So it somewhat seems any JWT handling library should include token verification.

Authorization header incudes extra quotations around token

When I log the headers in the request interceptor (on line 45 of angular-jwt.js) I get the following Authorization:

"Bearer "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0Mjc4NTE0MTR9.AxPfkGhggtt0iIn2OTorLjDDTdZ5Ut0mO6MBBD1kZY8""

If I bypass angular-jwt and add the token manually to the query method of a $resource query request the Authorization header is set and sent correctly. Here is the code I'm using, which uses angular-storage:

$resource(API_URL + '/endpoint/:id', {id: '@_id'}, {
    query: {
      method: 'GET',
      isArray: true,
      headers: {
        'Accept-Version': '2.0.0',
        Authorization: 'Bearer ' + store.get('auth-token')
      }
  });

The Authorization header with this method is:

"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0Mjc4NTE0MTR9.AxPfkGhggtt0iIn2OTorLjDDTdZ5Ut0mO6MBBD1kZY8"

I'm also using angular-storage to set the token in localStorage as shown below:

function login(email, password, success, error) {
  $http.post(API_URL + '/login', {
    email: email,
    password: password
  }).then(function(response) {
    response.data.token ? store.set(authKey, response.data.token) : store.remove(authKey);
    setSessionUser(response.data.user);
    success();
  }, function() {
      error();
  });
}

This is what I have in app.config for the provider:

  jwtInterceptorProvider.tokenGetter = ['config', function(config) {

    var token;

    // Skip authentication for any requests ending in .html
    if (config.url.substr(config.url.length - 5) == '.html') {
      return null;
    }

    return localStorage.getItem('auth-token');
  }];

Flexible authPrefix value

I would like to change the authPrefix from "Bearer " to "JWT ". I'm not seeing anything in docs or source code saying that's possible. Is that currently possible (maybe I'm missing it?) and/or are there plans of allowing flexibility for the authPrefix?

websocket support ?

is this proj support websocket? if it does , how?
what i think is auth the token when the socket is handshake, is that right?

support CORS option ?

Hi experts !

I really love angular-jwt and use it for my production projects. It runs so good until I have CORS issue.
I need to use interceptor for every get/post/put requests, but it also causes the CORS issue....

The url I browse is : https://axa.mydomain.com and my angularjs api is calling Google App Engine cloud endpoint which is https://axa-prod.appspot.com/_ah/api/v5/xxxxxx this request would trigger CORS issue due to interceptor force to append 'Authentication' header? (Correct me if i'm wrong.)

I've tried to confiig $httpProvider in app.js , but didn't get luck!

  delete $httpProvider.defaults.headers.common['X-Requested-With'];
  $httpProvider.defaults.withCredentials = true;
  $httpProvider.defaults.useXDomain = true;

Anyone have better suggestions to solve this CORS issue? Thanks!

1

Below is my angularjs code for interceptor

.config(function Config($httpProvider, jwtInterceptorProvider) {
  jwtInterceptorProvider.tokenGetter = function() {
    var access_key = localStorage.getItem('access_key');
    //console.log(access_key)
    return access_key
  }
  $httpProvider.interceptors.push('jwtInterceptor');
})

angular-jwt on client side does not decode flask-jwt tokens from server side

I am using Flask as a back end (api) and angularjs as a front end. For JWTs I am using Flask-JWT in my api. And I was trying to configure angular-jwt in my front end

On login, I call /api/v1/auth from angularjs app and I get the token. e.g.

 eyJhbGciOiJIUzI1NiIsImV4cCI6MTQzMjExNTAzMiwiaWF0IjoxNDMyMTE1MDAyfQ.eyJ1c2VyX2lkIjoxfQ.dmwvvgDinqWojmZ9ff1wHk_gDYM-dXNG-uTrabY9fFM

Then I store it in localStorage

localStorage['id_token'] = data.token;

But when I try to decode it in another part of my app, I get null

console.log('token expiration date', jwtHelper.getTokenExpirationDate(localStorage.getItem('id_token')));
console.log('token expired', jwtHelper.isTokenExpired(localStorage.getItem('id_token')));

Note that the algorithms that I have tried in back end are

bcrypt, sha512_crypt, or pbkdf2_sha512
// SECURITY_PASSWORD_HASH from https://pythonhosted.org/Flask-Security/configuration.html

Why doesn't it work?

In fact I see it getting decoded in http://jwt.io/

Does it require auth0

Does this library works with auth0 only or it can be used with on-premise ADFS without auth0?

unable to install angular-jwt with bower

tried to run
bower install --save angular-jwt

I got this error message:
$ bower install --save angular-jwt bower angular-jwt#* cached https://github.com/auth0/angular-jwt.git#0.1.3 bower angular-jwt#* validate 0.1.3 against https://github.com/auth0/angular-jwt.git#* bower ECONFLICT Unable to find suitable version for angular-jwt
I'm currently using Angular 1.5.8

Refresh token issue with promisse and first request

Im having an issue with the library,
basically when the token has expired and i refresh the web page,
then the jwtInterceptor is called i then return a promise that will resolve to the new access token, however the request that originated the first interceptor invocation will be executed without the access token http param, giving me an 401 for that request,
here is my interceptor

app.config([
        '$httpProvider', 'jwtInterceptorProvider', function ($httpProvider, jwtInterceptorProvider) {
            jwtInterceptorProvider.tokenGetter = [
                'jwtHelper', '$http', 'authService', 'config', 'ngAuthSettings', '$location', '$q',
                function (jwtHelper, $http, authService, config, ngAuthSettings, $location, $q) {
                    var authData, promisse;
                    authData = authService.authData();
                    if (config.url.substr(config.url.length - 5) === '.html') {
                        return null;
                    }
                    if (authData === null || config.url.indexOf(ngAuthSettings.apiBaseUri + 'oauth') === 0) {
                        return null;
                    } else if (jwtHelper.isTokenExpired(authData.token)) {
                        promisse = authService.refreshToken();
                        return promisse.then((function (token) {
                            return token;
                        }), function () {
                            $location.path('/signin');
                            return null;
                        });
                    } else {
                        return authData.token;
                    }
                }
            ];
            $httpProvider.interceptors.push('jwtInterceptor');
        }
    ]);

Unknown Provider... ProviderProvider?

Unknown provider: jwtInterceptorProviderProvider <- jwtInterceptorProvider <- $http

in the top level module i've injected angular-jwt into the config module like this:

angular.module("myproject.config", ["angular-jwt"]);

my config module looks like this:

(function () {
  "use strict";
  angular.module("myproject.config")
    .config(config);

  config.$inject = ["$locationProvider", "$httpProvider", "jwtInterceptorProvider"];

  function config($locationProvider, $httpProvider, jwtInterceptorProvider) {
    ...
    $httpProvider.interceptors.push("jwtInterceptorProvider");

    // add jwt authentication header to each request
    jwtInterceptorProvider.authPrefix = "JWT ";
    jwtInterceptorProvider.tokenGetter.$inject = ["jwtAuthentication"];
    jwtInterceptorProvider.tokenGetter = function (jwtAuthentication) {
      return jwtAuthentication.getToken();
    }; 
  }  
})();

please pardon my question, I am a versed programmer but I have little experience with angularjs outside of tutorials.

Minification problem

Not sure if it is about this project or $httpProvider.

When I do $httpProvider.interceptors.push('jwtInterceptor');

I got the error Error: [$injector:unpr] Unknown provider: aProvider <- a

Only when I am doing minification. If I comment out that line then I do not get that error.

Add support for nbf(not before) during token validity check

Hi,

Are there any plans to add support for the nbf claim when checking if the token in valid. From my understanding of the specification if the claim exists then the token is only valid if the current time is after the time given(with a few minutes leeway to account for clocks that are slightly off).

I am more than happy to implement this if it going to be helpful for others.

$http.jsonp token not in header

I am trying to use angular-jwt in service but it does not append authorization on http call, can it be use with $http.jsonp:

  .config(function Config($httpProvider, jwtInterceptorProvider) {
    jwtInterceptorProvider.tokenGetter = ['merchantService', function(merchantService) {
        merchantService.doSomething();
        return localStorage.getItem('token');
    }];

    $httpProvider.interceptors.push('jwtInterceptor');
  })
  .service('Merchant', ['$http', function($http) {
    var baseUrl = "http://test.com";

    return {
        terminal: function(success, error) {
            $http.jsonp(baseUrl + '/tests?callback=jsonp_callback').success(success).error(error)
        }
    } 
  }]);

If I am using $http call, I get this error:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Can this be the reason?

Non-documented (critical) feature.

isTokenExpired() function has a critical undocumented (sorry for wrong title) optional parameter (time offset, in seconds) that, if ommited and the client is in any other timezone than GMT 0, will cause the function to return the wrong result.

Why not make it automatic (if no offset is passed) and use new Date().getTimezoneOffset() * 60 instead of assuming no offset?

How to handle when multiple async requests are being done

Hi guys.
I'm have the following problem:

When my token is invalid it goes an requests a new token with the refresh with this code based on described in the docs:

// retrieve the JWT which is set during the Authentication
var jwt = $localStorage.JWT;
if(jwt)
{
  // check if the token is expired?
  if(jwtHelper.isTokenExpired(jwt))
  {
    // refresh the token
    return $http({
      url: 'http://mydomain.dev:8080/token',
      method: 'GET',
      headers: {Authorization: 'Bearer ' + jwt}
    }).then( function successCallback(response)
      {
        // got a valid response so lets provide our storages with the new token
        $localStorage.JWT = response.data
        return response.data;
      },
      function errorCallback()
      {
        // somethings wrong with the token. Invalidate the tokens here
        delete $localStorage.JWT;
      });
  }
  else
  {
    return jwt;
  }

But i have a route which resolves multiple things e.g.
getAllUsers()
getSomethingElseImportant()

so the interceptor will be called twice, and so the token will be acquired and blacklisted.
But the second request will be doing the exact same thing and thus the backend will throw an exception that the token is blacklisted.

Any thoughts or solutions?

Cannot send requests with angular-jwt in IE9

Hi,
First of all, thanks for this great module, it helps me a lot!

I have an issue here, this module works great in FF/Chrome, but when I want to test my app in IE9(I did not tried other IE versions), it is not working any more! The IE Dev tool showed that only requests with "skipAuthorization: true" can be sent and respond the correct response, while requests without "skipAuthorization: true" cannot even be sent.
I have checked that the token has been saved to localStorage correctly.

AngularJS 1.2.26
angular-jwt The latest version
IE9

Could you please help me with this? Thanks in advance!

unauthenticatedRedirector Error

jwtOptionsProvider.config({
tokenGetter: ['store', function (store) {
return store.get('access_token');
}],
whiteListedDomains: ['api.servidor.com', 'localhost'],
unauthenticatedRedirector: ['$state', function ($state) {
$state.go('login');
}]
});

exception:

config.unauthenticatedRedirector is not a function. (In 'config.unauthenticatedRedirector($location)', 'config.unauthenticatedRedirector' is an instance of Array)
column: 45
line: 260
message: "config.unauthenticatedRedirector is not a function. (In 'config.unauthenticatedRedirector($location)', 'config.unauthenticatedRedirector…"

authmanager is polluting $rootScope

$rootScope.isAuthenticated = false;

It’s a bad idea to attach too much logic to this global context, in the same way that it’s not a good idea to dirty the JavaScript global scope.

Instead, authManager should have an isAuthenticated property that can be used from anywhere.

// ...
     var isAuthenticated = false;

      function authenticate() {
        isAuthenticated = true;
      }

      function unauthenticate() {
        isAuthenticated = false;
      }
// ...

return {
// ...
    isAuthenticated : isAuthenticated,
}

https://www.thinkingmedia.ca/2015/01/learn-how-to-use-scopes-properly-in-angularjs/

Unable to use angular-jwt with AppGyver Supersonic

AppGyver's Supersonic uses bower out of the box, after installing the bower package I am attempting to inject angular-jwt into my AuthService but I am getting an $injector issue as it can't find this module?

I've also tried just including the script tag that links to cdnjs in the layout to no avail.

Probably not an angular-jwt issue perse but I thought I'd open an issue to attempt to get some help!

I would really appreciate it!

Any chance of getting a react-jwt?

Hi,
Thank for this module, I've been using it for several angular projects.
Now, I'm about to start a react-native app (using Reflux) and I'm library shopping a bit. I'm currently working on the authentication mechanisms, and was kind of hoping to be able to port my angular authentication services to Reflux pattern, but can't seem to find a jwt token library with all the goodies like in this (like checking if the token is expired, getting the expiration date, validity and so on).

So, is there any chance of seing a react port of this library?
Thanks!

Use jwtInterceptor to send the token as a request param?

I am using WebSockets and, for reasons that have to do with my back-end framework, can only use request params to send the token. Is there a way to create a jwtInterceptor that will accomplish this, or is sending via header the only possibility?

Rejecting requests

A common logic flow for JWT is:

if token available // e.g. from local storage
    if token is not expired
        return token
    if token is expired and refresh token is available
        refresh token, return new token
else
    go to sign-in page

I can't find a way to accomplish the else clause with this library -- rejecting the HTTP request(s) that were intercepted and navigating to the sign-in page. Is there a usage pattern for this library to accomplish this?

Using with ngResource?

Hi,

I'm new to AngularJs and just strugging using this alongside ngResource. What is the correct syntax I need to manage the angular-jwt import alongside ngResource?

var loginModule = angular.module("loginModule", ["angular-jwt", "ngResource"]);
loginModule.controller("LoginController", [jwtHelper, "$resource", function (jwtHelper, $resource) {
    this.login = function(auth) {
             <snip>
    };
}]);

I'm having trouble seeing jwtHelper, so I think I'm making an error defining my controller using both jwtHelper and ngResource...? Any insight appreciated

authManager.checkAuthOnRefresh not working

// src/angularJwt/services/authManager.js

function checkAuthOnRefresh() {
        // When a location change is detected
        $rootScope.$on('$locationChangeStart', function () {
          var tokenGetter = config.tokenGetter;
          var token = null;
          // Try to get jwt token...
          if (Array.isArray(tokenGetter)) {
            token = $injector.invoke(tokenGetter, this, {});
          } else {
            token = config.tokenGetter();
          }
          if (token) {
            if (!jwtHelper.isTokenExpired(token)) {
                     // If token and not expired authenticate, ok lgtm
                     authenticate();
            }
            // But what happens if not? when token had expired or there is no token? 
            // Shall an 'unauthenticated' event be fired?
          }
        });
      }

But there´s more... if checkAuthOnRefresh fires unauthenticated event every time that a locationChangeStart is produced the user won't be able to go to the login page.

( Because redirectWhenUnauthenticated will be fired with another locationChangeStart causing an infinite loop. )

Refresh Token example question

In the Refresh Token code example, there is a line that shows how to retrieve the new token for the refresh:

var refreshToken = localStorage.getItem('refresh_token');
  1. At what point or where is this local storage value set?
  2. Is there a reason why a new token is generated instead of just sending the token back with a new expiry date?

Thanks

Syntax error in README.md

Hello, there's a semicolon that shouldn't be there, that's all.

angular
  .module('app', ['angular-jwt'])
  .config(function Config($httpProvider, jwtOptionsProvider) {
    // Please note we're annotating the function so that the $injector works when the file is minified
    jwtOptionsProvider.config({
      tokenGetter: ['myService', function(myService) {
        myService.doSomething();
        return localStorage.getItem('id_token');
      }]; // FIXME: This semicolon should be deleted
    });

authManager unable to invoke some tokenGetter dependencies

For example, when I use the example provided in the docs to bypass sending JWTs for template requests:

UPDATE: a Plunker demonstrating the issue

config.js

(function() {
    'use strict';

    angular
        .module('app.core')
        .config(appConfig);

    appConfig.$inject = ['$httpProvider', '$ionicConfigProvider', '$localStorageProvider', 'jwtOptionsProvider', 'API'];

    function appConfig($httpProvider, $ionicConfigProvider, $localStorageProvider, jwtOptionsProvider, API) {
        // ~snipped~

        // JWT Interceptor
        $httpProvider.interceptors.push('jwtInterceptor');

        // JWT Configration Options
        jwtOptionsProvider.config({
            // options here are the request options
            tokenGetter: ['options', '$localStorage', function(options, $localStorage) {
                var token = null;
                if (options.url.substr(options.url.length - 5) !== '.html') {
                    token = $localStorage.token;
                }
                return token;
            }],
            whiteListedDomains: [
                API.BASE
            ]
        });
    }
})();

And injecting the authManager and calling its checkAuthOnRefresh() during the run phase:

app.js

(function() {
    'use strict';

    angular
        .module('app', [
            'app.core',
            // ~snipped~
        ])

        .run(bootstrapApp);

    bootstrapApp.$inject = ['$ionicPlatform', 'authManager', 'amMoment'];

    /* @ngInject */
    function bootstrapApp($ionicPlatform, authManager, amMoment) {
        authManager.checkAuthOnRefresh();

        // ~snipped~
    }
})();

I get an error saying that 'optionsProvider' is unavailable when invoked from the authManager:

Error: [$injector:unpr] Unknown provider: optionsProvider <- options

The options are available to the tokenGetter when making requests though.

Angular jwt cannot decode token from Laravel backend

Hello!

Thanks for the jwt helper for angular.
It is very awesome, and easy to use.
It is first time I am using JWT based auth.
After login, laravel backend is sending me a token.
I am using jwtHelper to decode, I can only get url, not username,...
Is it normal?

Thanks

Support for changing the authorization prefix.

Hello and congrats on the library.

I would recommend to add a config function so I can change the Authorization prefix.

By default all the Requests are being send with the prefix: Authorization: Bearer [Token]

In my case, I must send it with Authorization: JWT [Token].

I can change it by modifying the library itself (this.authPrefix = 'Bearer '; ) but it would be nice If I could do it straight from my code.

Thanks.

Question - Using angular-jwt with Restangular.

Something tells me I should be able to get some help owing to the creator of this repo.

I would like to switch over from our painful token/csrf/cookie based auth system to JWTs... We are using Restangular in production, and I have a number of factories providing Restangular instances. Would the setup be any different? I.e. need to use a global $http interceptor as shown vs. an interceptor for a particular Restangular.withConfig() ?

If I can get my head around it I'd be happy to contribute back to the docs with an example. Thanks.

Null Validation in isTokenExpired function

Hi

I think it could be a good idea to add a extra null validation in isTokenExpired function, something like :

this.isTokenExpired = function(token) {
if (!token) {
return false;
}
var d = this.getTokenExpirationDate(token);
if (!d) {
return false;
}
// Token expired?
return !(d.valueOf() > new Date().valueOf());
};

Regards

Support for compression algorithms

Hey guys, is there a way to automatically support DEFLATE or any other algorithm?

In theory, we can always get the token, process and then send it to the library so it can detect if expired or not and all those things.

Is there a good way to do this? If there was a method we could override would be nice, or some interceptor.

Thanks!

save the token un the $scope?

It's posible to use angular-jwt saving the token in the $scope instead of the localStorage?

It's not possible to inject the €rootScope in the Config function

jwtInterceptor - tokenGetter is not called because of angular caching

Hi guys. I noticed that sometimes tokenGetter is not called during request and instead of sending refresh token request to fetch updated access token, interceptor just do nothing. As I understand angular caches headers and because of next lines the tokenGetter is not called:

request.headers = request.headers || {};
// Already has an Authorization header
if (request.headers[config.authHeader]) {
    return request;
}

Maybe it will be better to add configurable parameter, something like "forceHearedUpdate" and if this parameter is true then omit the if (request.headers[config.authHeader]) branch of code.

Unable to install new 0.1.0 release due to bower install attempt

When attempting to update or install the new release, it attempts to run bower install upon installation causing the npm package installation to fail if bower isn't available.

$ npm install --save [email protected]

> [email protected] install /redacted/path/node_modules/angular-jwt
> bower install

sh: bower: command not found
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: [email protected]
npm ERR! Linux 4.4.16-1-lts
npm ERR! argv "/home/noderat/.nvm/versions/node/v6.3.1/bin/node" "/home/noderat/.nvm/versions/node/v6.3.1/bin/npm" "install" "--save" "[email protected]"
npm ERR! node v6.3.1
npm ERR! npm  v3.10.5
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn

npm ERR! [email protected] install: `bower install`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the [email protected] install script 'bower install'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the angular-jwt package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     bower install
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs angular-jwt
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls angular-jwt
npm ERR! There is likely additional logging output above.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.