Search code examples
angularjspassport.jspassport-localjson-web-tokenexpress-jwt

Using Passport for Authentication of API Endpoints


Following a couple tutorials on adding authentication using jsonwebtoken, passport, and passport-local I've become stuck on integrating it into my project. I want it so that any requests to any of the API endpoints require authentication, and also any requests to the front end which touch the API require authentication.

What is happening now is I can get a user to log in and register but once they are logged in they are still unable to visit a page which is requiring authentication. The user gets a 401 error. It's like the token isn't being passed correctly in the request.

I tried adding an 'auth interceptor' too

myApp.factory('authInterceptor', function ($rootScope, $q, $window) {
  return {
    request: function (config) {
      config.headers = config.headers || {};
      if ($window.sessionStorage.token) {
        config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
      }
      return config;
    },
    response: function (response) {
      if (response.status === 401) {
        // handle the case where the user is not authenticated
      }
      return response || $q.when(response);
    }
  };
});

myApp.config(function ($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
});

But this didn't seem to do the trick either.
What am I forgetting or missing?

EDIT:

After entering creds and clicking log in I get this error in chrome console

GET http://localhost:3030/members/ 401 (Unauthorized)

But my nav links show up as they're supposed to after I've successfully authenticated.
I also get this error in my terminal where I'm running Node

UnauthorizedError: No authorization token was found
    at middlware (/ncps-mms/node_modules/express-jwt/lib/index.js)
    ...

EDIT:

It has a lot to do with this line of my server routes when I inject my auth object. Basically I think my auth token isn't getting sent with my GET request. But I thought that this is what happens when I pass my auth object into the GET request.

EDIT:

Added image of GET request.
Screenshot of GET request in Chrome.

EDIT/UPDATE:

I believe I've made my way past my authentication problem but the issue of my members-view state continues to fail to render after authenticated. I've pushed my latest changes to github and if you pull the latest and run you will see that you can authenticate but clicking the View link fails to load the view.


Solution

  • https://github.com/gh0st/ncps-mms works fine for me after a few fixes for resolve...

    See https://github.com/gh0st/ncps-mms/pull/2

    client/src/routes.js

    /* jshint esversion: 6 */
    /* jshint node: true */
    import angular from 'angular';
    import 'angular-ui-router';
    
    angular.module('ncps.routes', ['ui.router'])
    .config(($stateProvider, $urlRouterProvider) => {
        $urlRouterProvider.otherwise('/members/login');
    
        $stateProvider
        .state('login', {
            url: '/members/login',
            templateUrl: 'members/members-login.html',
            controller: 'AuthController',
            onEnter: ['$state', 'auth', function($state, auth) {
                if (auth.isLoggedIn()) {
                    console.log('Going to /members/...');
                    $state.go('members', {
                        // 'headers': {
                        //     'Authorization': 'Bearer ' + auth.getToken()
                        // }
                    });
                }
            }]
        })
        .state('register', {
            url: '/members/register',
            templateUrl: 'members/members-register.html',
            controller: 'AuthController',
            onEnter: ['$state', 'auth', function($state, auth) {
                if (auth.isLoggedIn()) {
                    $state.go('members');
                }
            }]
        })
        .state('members', {
            url: '/members',
            templateUrl: 'members/members-view.html',
            resolve: {
                members: function($http, auth) {
                    console.log('Trying to get /members....');
                    return $http.get('/members', {
                        headers: {
                            'Authorization': 'Bearer ' + auth.getToken()
                        }
                    }).then(function(response){
                        return response.data;
                    });
                }
            },
            controller: 'MembersController as membersCtrl'
        })
        .state('new', {
            url: '/members/add',
            templateUrl: '/members/members-add.html',
            controller: 'MembersSaveController as newMemberCtrl'
        })
        .state('test', {
            url: '/members/test',
            template: 'This is a test.'
        });
    });
    

    client/src/controllers/controllers.js

    /* jshint esversion: 6 */
    /* jshint node: true */
    import angular from 'angular';
    angular.module('ncps.controllers', [])
    
    .controller('MembersController', ['$http', 'auth', 'members', function($http, auth, members) {
        console.log('Members retrieved');
        this.members = members;
    }])
    
    .controller('MembersSaveController', function($stateParams, $state, $http) {
        this.member = $state.member;
    
        this.saveMember = function(member) {
            $http.post('/members', member).then((res, member) => {
                $state.go('members');
            });
        };
    })
    
    .controller('NavController', ['$scope', 'auth', function($scope, auth) {
        $scope.isLoggedIn = auth.isLoggedIn;
        $scope.currentUser = auth.currentUser;
        $scope.logOut = auth.logOut;
    }])
    
    .controller('AuthController', ['$scope', '$state', 'auth', function($scope, $state, auth) {
        $scope.user = {};
    
        $scope.register = function() {
            auth.register($scope.user).error(function(error) {
                $scope.error = error;
            }).then(function() {
                $state.go('members');
            });
        };
    
        $scope.logIn = function() {
            auth.logIn($scope.user).error(function(error) {
                $scope.error = error;
            }).then(function() {
                $state.go('members');
            });
        };
    
        $scope.logOut = function() {
            auth.logOut().error(function(error) {
                $scope.error = error;
            }).then(function() {
                $state.go('members');
            });
        };
    }]);