身份验证正在返回" 401(未授权)"什么时候不应该

时间:2015-06-26 22:10:25

标签: angularjs node.js authentication sails.js passport-local

我第一次设置了身份验证功能,并且在用户登录后收到了一些意想不到的结果。一位同事给了我一个带有工作身份验证的应用程序来模拟我的应用程序,看起来就像我拥有的​​一切完成是正确的。

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

我的源代码(现在)已公开存储...后端API位于Github上(API Github),前端代码位于此处(Front-End Github

基本上发生的是用户

  1. 点击登录按钮,触发此功能

    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. 在该步骤中,护照应该做并登录用户

    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 }); }
        });
       }
     ));
    
  4. 在控制台中,我总是认为这是成功的。

    控制台显示:

    User logged in:  Object {firstName: "John", lastName: "Doe", email: "john_doe@work.com", activated: true, isUser: true…}
    
    1. 然后,我对发生的事情的理解变得有些模糊。我知道应用程序然后尝试查看用户是否经过身份验证。 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); }
      },
      
    3. 然后它失败了:( GET http://localhost:1337/user/authenticated 401 (Unauthorized) req.isAuthenticated和req.user.isUser都没有通过。我把它们分开来进行单独测试,它们都不是真的。" isUser"是value我默认为true,因此对于db中的每个用户都应该是true.req.isAuthenticated也失败了,我不完全理解。

      有人对我的问题有所了解吗?我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

如果您的前端应用程序与后端应用程序the AJAX requests will not include the session 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

的指示检查the server side configuration

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

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

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

答案 1 :(得分:2)

Usualy 401' Unauthorized'错误实际上是指一个凭据错误,而不是403错误,它指的是一个真正的未经授权的错误(禁止),因此您应该首先检查您的客户端Postman以测试它然后转移到客户端。

尽管如此,我强烈建议您从该github项目中删除并使用本教程来实现您的passport.js身份验证,因为您只需要执行2行代码和一些配置,而不是弄乱代码: https://www.bearfruit.org/2014/07/21/tutorial-easy-authentication-for-sails-js-apps/

答案 2 :(得分:2)

由于passport.js使用策略的基础概念,因此您需要确保使用正确的策略进行身份验证。我没有看到任何名为“用户”的策略

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。