当它不应该时,authentication返回“401(未授权)”

我第一次设置了身份validationfunction,并且在用户login后得到了一些意想不到的结果。一位同事给了我一个有效身份validation的应用程序来模拟我的应用程序,好像我所做的一切都是正确的。

我在前端使用AngularJS,SailsJS后端框架和PassportJS身份validation中间件。

我的源是(现在)公开存储…后端API在Github这里( API Github )和前端代码在这里( 前端Github )

基本上发生的是用户

  1. 点击loginbutton,触发这个function

    login: function (credentials) { return baseAuth.customPOST(credentials, 'login').then(function (user) { $log.debug('User logged in: ', user); isAuthenticated = true; return user; }); }, 
  2. 该customPOST的控制器逻辑是这样的

     login: function (req, res, next) { passport.authenticate('local', function (err, user, info) { if (err) { return res.json(err); } else if (user) { req.logIn(user, function (err) { if (err) { return res.json(err); } return res.json(user); }); } else { return res.json(400, info); } })(req, res); }, 
  3. 在这一步,护照应该做的事情,并login用户

     passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, next) { User.findOne({ email: email }) .exec(function (err, user) { if (err) { return next(err); } if (user) { if (user.activated) { bcrypt.compare(password, user.password, function (err, valid) { if (err) { next(err); } if (valid) { return next(null, user, { message: 'Logged In' }); } else { return next(null, false, { message: 'Incorrect password'}); } }); } else { next(null, false, { message: 'User is not activated. Please contact admins.'}); } } else { next(null, false, { message: 'Could not find user with email ' + email }); } }); } )); 

在控制台,我总是得到这是成功的。

控制台读取:

 User logged in: Object {firstName: "John", lastName: "Doe", email: "john_doe@work.com", activated: true, isUser: true…} 
  1. 然后,我对发生的事情的理解变得模糊起来。 我知道应用程序然后尝试查看用户是否通过身份validation。 IsAuthenticated被触发,在AngularJS中看起来像这样:

     isAuthenticated: function (force) { var deferred = $q.defer(); if (isAuthenticated && currentUser) { deferred.resolve(currentUser); } else { return baseAuth.customGET('authenticated').then(function (user) { deferred.resolve(currentUser); isAuthenticated = true; currentUser = user; return user; }); } return deferred.promise; } 
  2. 它在后端UserController中击中了这个动作

     isAuthenticated: function (req, res) { if (req.isAuthenticated() && req.user.isUser) { return res.json(req.user); } else { return res.send(401); } }, 

然后它失败:( GET http://localhost:1337/user/authenticated 401 (Unauthorized)既不req.isAuthenticated也不req.user.isUser通过。我已经分离出来单独testing,都不是真实的。“isUser “是一个默认为true的值,对于db中的每个用户都是如此。req.isAuthenticated也失败了,我不完全明白。

任何人都有一些洞察我的问题? 我在这里做错了什么?

如果您的前端应用程序与您的后端应用程序具有不同的来源, 那么AJAX请求将不包含会话cookie,而req.isAuthenticated()永远不会返回true。

使用withCredentials选项强制它。

 $http({ withCredentials: true, ... }) 

看来Restangular使用相同的选项:

https://github.com/mgonto/restangular#setdefaulthttpfields

https://docs.angularjs.org/api/ng/service/$http#usage

编辑:你也应该检查idbehold指出的服务器端configuration


正如Matan所build议的那样,您应该尝试一下服务器端的sails-generate-auth生成器。

https://github.com/sails101/even-more-passport

https://github.com/kasperisager/sails-generate-auth

Usualy一个401'未经授权'的错误实际上是指凭证错误,而不是403错误,这是指一个真正的未经授权的错误(禁止),所以你应该检查你的客户与邮递员首先testing它,然后移动到客户端。

尽pipe我强烈build议你从这个github项目中下载并使用本教程来实现你的passport.jsauthentication,因为你只需要执行2行代码和一些configuration,而不会让代码混乱: https:/ / /www.bearfruit.org/2014/07/21/tutorial-easy-authentication-for-sails-js-apps/

由于passport.js使用策略的基本概念,因此需要确保使用正确的身份validation。 我没有看到任何一个叫做“用户”的策略

 passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, next) { User.findOne({ email: email }) .exec(function (err, user) { if (err) { return next(err); } if (user) { if (user.activated) { bcrypt.compare(password, user.password, function (err, valid) { if (err) { next(err); } if (valid) { return next(null, user, { message: 'Logged In' }); } else { return next(null, false, { message: 'Incorrect password'}); } }); } else { next(null, false, { message: 'User is not activated. Please contact admins.'}); } } else { next(null, false, { message: 'Could not find user with email ' + email }); } }); } )); 

应该改成

 passport.use('user', new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, next) { User.findOne({ email: email }) .exec(function (err, user) { if (err) { return next(err); } if (user) { if (user.activated) { bcrypt.compare(password, user.password, function (err, valid) { if (err) { next(err); } if (valid) { return next(null, user, { message: 'Logged In' }); } else { return next(null, false, { message: 'Incorrect password'}); } }); } else { next(null, false, { message: 'User is not activated. Please contact admins.'}); } } else { next(null, false, { message: 'Could not find user with email ' + email }); } }); } )); 

还要确保你的用户的isUser标志被设置为true。