2015-12-18 46 views
0

背景:我使用节点/表达为我的后端,蒙戈作为数据库,和角为前端创建的应用程序。我正在使用jsonwebtoken来验证用户。用户登录后,令牌将存储在本地存储中,用于验证所有请求。在用户登录后, 的名称和用户名经Auth.getUser()检索,这是角工厂方法,其从后端获取数据。每个请求意味着堆栈登录错误:没有令牌所提供

问题:我无法得到用户重定向到主页,因为下面的代码不运行:

vm.login = function() {  
     vm.error = ''; 

     Auth.login(vm.loginData.username, vm.loginData.password) 
     .then(function(data) { 
      Auth.getUser() 
      .then(function(data) { 
       vm.user = data.data; 
      }); 

      if (data.success) { 
       $location.path('/'); 
      } else { 
       vm.error = data.message; 
       console.log(vm.error); 
      } 

     }); 
    } 

我不重定向到主页,但我也不会在开发控制台或我的终端中收到任何消息。

当我检查通过开发者控制台中的本地存储,我没有令牌。但是,我可以使用POSTMAN成功登录/注册/发布数据。我认为问题可以通过以下步骤来充实:

1.该用户登录时,和令牌被存储在本地存储 2. Auth.getUser()被假设为以请求来自后端的用户数据。 。每个请求需要经由jsonwebtoken.verify()方法来进行验证令牌。 。对于某些原因,令牌不发送给我的后端,所以这不会运行:

api.use(function(req,res,next) { 
     console.log('someone tried to access a secure page'); 

     var token = 
      req.body.token || req.param('token') || req.headers['x-access-token']; 

     if (token) { 
     //code 


     } else { 
     res.status(403).send({ success: false, message: "No Token Provided"}); 

这里是什么,我认为相关的文件:

后端:

var mongoose = require('mongoose'); 
var User = require('../models/user.js'); 
var Story = require('../models/story.js'); 
var config = require('../../config/config.js'); 
var jsonWebToken = require('jsonwebtoken'); 
var sessionSecret = config.sessionSecret; 


function createToken(user) { 

    var token = jsonWebToken.sign({ 
     id: user._id, 
     name: user.name, 
     username: user.username 
    }, sessionSecret, {expiresInMinutes: 1440}); 

    return token; 
} 

module.exports = function(app, express) { 
    var api = express.Router(); 


api.post('/login', function(req,res) { 

     User.findOne({username: req.body.username}) 
      .select('password').exec(function(err, user) { 
       if (err) { 
        res.send(err); 
        return; 
       } else { 
        if (!user) { 
         res.send('user does not exist!'); 
        } else { 
         var isPasswordValid = user.comparePassword(req.body.password); 
         if (!isPasswordValid) { 
          res.send('wrong password!'); 
         } else { 

          var token = createToken(user); 
          res.json(
           {success:true, 
           message:'successfully logged in!', 
           token: token}); 
         } 
        } 
       } 
      }) 
     }); 


    api.use(function(req,res,next) { 
     console.log('someone tried to access a secure page'); 

     var token = 
      req.body.token || req.param('token') || req.headers['x-access-token']; 

     if (token) { 
      jsonWebToken.verify(token, sessionSecret, function(err, decoded) { 

       if(err) { 
        res.status(403).send({ success: false, message: "Failed to authenticate user"}); 

       } else { 

        // 
        req.decoded = decoded; 
        next(); 
       } 
      }); 
     } else { 
        **//*****the message sent to my frontend********* 
      res.status(403).send({ success: false, message: "No Token Provided"}); 
     } 

    }); 

    api.get('/me', function(req,res) { 
     res.send(req.decoded); 
    }) 

    app.use('/api', api); 
} 

前端

角工厂:从后端检索数据

var authService = angular.module('authService', []); 

authService.factory('Auth', function($http, $location, $q, AuthToken) { 


    var authFactory = {}; 

    authFactory.login = function(username,password) { 

     return $http.post('/api/login', { 
      username: username, 
      password: password 
     }).success(function(data) { 
      AuthToken.setToken(data.token); 
      return data;   
     }) 
    } 


    authFactory.getUser = function() { 

     if (AuthToken.getToken()) { 
      return $http.get('/api/me'); 
     } else { 
      return $q.reject({message: 'unable to get data'}); 
     } 
    } 


    return authFactory; 

}); 

authService.factory('AuthToken', function($window) { 

    var authTokenFactory = {}; 

    authTokenFactory.getToken = function() { 
     return $window.localStorage.getItem('token'); 
    } 

    authTokenFactory.setToken = function(token) { 
     if (token) { 
      $window.localStorage.setItem('token', token); 
     } else { 
      $window.localStorage.removeItem('token'); 
     } 
    } 
    return authTokenFactory; 
}); 

authService.factory('AuthInterceptor', function($q, $location, AuthToken) { 

var interceptorFactory = {}; 


interceptorFactory.request = function(config) { 

    var token = AuthToken.getToken(); 

    if(token) { 

     config.headers['x-access-token'] = token; 
    } 
    return config; 


}; 

interceptorFactory.responseError = function(response) { 
     if (response.status === 403) { 
      $location.path('/login'); 
      return $q.reject(response); 
     } 
    } 
}); 

mainController

angular.module('MainController', []) 

    .controller('mainController', ['$rootScope','$location','Auth', function($rootScope,$location, Auth) { 

    var vm = this; 

    vm.isLoggedIn = Auth.isLogged(); 

    $rootScope.$on('$routeChangeStart', function() { 

     vm.isLoggedIn = Auth.isLogged(); 
      Auth.getUser().then(function(data) { 
       vm.user = data.data; 
      })        
     }) 


    vm.login = function() {  
     vm.error = ''; 

     Auth.login(vm.loginData.username, vm.loginData.password) 
     .then(function(data) { 
      Auth.getUser() 
      .then(function(data) { 
       vm.user = data.data; 
      }); 

      if (data.success) { 
       $location.path('/'); 
      } else { 
       vm.error = data.message; 
       console.log(vm.error); 
      } 

     }); 
    } 

的index.html

<!DOCTYPE html> 

<html ng-app="myApp"> 
    <base href="/"> 
    <head> 
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> 


     <script src="https://code.angularjs.org/1.4.0-rc.1/angular.min.js"></script> 
     <script src="https://code.angularjs.org/1.4.0-rc.1/angular-route.min.js"></script> 
      <!--angular services --> 
     <script src="app/auth/authService.js"></script> 
     <!--angular controllers --> 
     <script src="app/controllers/mainController.js"></script> 

     <script src="app/app.routes.js"></script> 
     <script src="app/app.js"></script> 
    </head> 

    <body> 
     <div class="container"> 
      <div ng-view></div> 
     </div> 



    </body> 
</html> 

的login.html

<div class="container" ng-controller="mainController as login"> 

    <form method="post" ng-submit="login.login()"> 
     username: <input type="text" name="username" ng-model="login.loginData.username"> 
     password: <input type="password" name="password" ng-model="login.loginData.password"> 
     <button type="submit" class="btn btn-success">submit</button> 


    </form> 
</div> 

进一步的代码将根据要求提供。我会很感激任何帮助,因为我花了无数小时来解决这个问题。

+0

虽然'$ HTTP .get('/ api/me');',你没有发送任何'token' – Rayon

+0

你可以使用['Interceptorors'](https://docs.angularjs.org/api/ng/service/$http)在每个http请求中发送令牌st' – Rayon

+0

我以为我通过config.headers ['x-access-token'] =令牌发送了令牌。如果您有不同的方式,您可以详细说明如何发送代币? – Frosty619

回答

0

我猜重定向是否发生在获取数据之前:

vm.login = function() {  
    vm.error = ''; 

    Auth.login(vm.loginData.username, vm.loginData.password) 
    .then(function(resp) { // <------changed the arg to 'resp' 
     Auth.getUser() 
     .then(function(data) { 
      vm.user = data.data; 
      if (resp.success) { // <------put the condition here with 'resp' 
       $location.path('/'); 
      } else { 
       vm.error = resp.message; 
       console.log(vm.error); 
      } 
     }); 
    }); 
} 

另外一个变化,我可以建议你使用的.success().then(),而不是在这里:

return $http.post('/api/login', { 
     username: username, 
     password: password 
    }).then(function(data) { // <--------change to `.then()` 
     AuthToken.setToken(data.token); 
     return data;   
    }) 
+0

@ Frosty619你能否确认你能够将这些'vm.loginData.username,vm.loginData.password'传递给函数。 – Jai

+0

如果您查看angularFactory部分下的authFactory.login方法,您将看到它在登录成功后返回数据,然后使用AuthToken.setToken(data.token)将令牌设置为本地存储。由于我在本地存储中获取令牌,因此我认为可以安全地假设我能够将登录参数传递给函数 – Frosty619

+0

这是一个猜测,但我觉得你必须返回'interceptorFactory'。 – Jai

相关问题