认证是返回" 401"当它不应该 [英] Authentication is returning "401 (Unauthorized)" when it shouldn't

查看:408
本文介绍了认证是返回" 401"当它不应该的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立了我的第一次认证功能和我得到一些意想不到的结果,用户已被记录后,一位同事给我的应用程序一起工作的认证后,我的应用模式,它看起来像我的一切做的是正确的。

我使用的前端AngularJS,SailsJS后端框架, PassportJS 认证的中间件。

我的来源是公开...存储在后端API是在Github这里( API Github上(现在) )和前端code被发现这里(前端Github上

基本上什么情况是,用户


  1. 点击登录按钮,这将触发该功能。

     登录:功能(凭证){
        返回baseAuth.customPOST(凭据,'登录'),然后(功能(用户){
            $ log.debug(用户登录:用户);
            isAuthenticated = TRUE;
            返回用户;
        });
    },


  2. 对于customPOST控制器逻辑是这样的。

     登录:功能(REQ,资源,下一个){
       passport.authenticate('当地',函数(ERR,用户信息){
           如果(ERR){返回res.json(ERR); }
           否则如果(用户){
               req.logIn(用户,功能(错误){
                   如果(ERR){返回res.json(ERR); }
                   返回res.json(用户);
               });
           }其他{返回res.json(400,资讯); }   })(REQ,RES);},


  3. 在这一步,应该护照做它的东西和登录用户

      passport.use(新LocalStrategy({usernameField:电子邮件,passwordField:密码},
    功能(电子邮件,密码,下一次){
       User.findOne({电子邮件:电子邮件})
           .exec(函数(ERR,用户){
               如果(ERR){返回下一个(ERR); }
               如果(用户){
                    如果(user.activated){
                    bcrypt.compare(密码,user.password的,功能(ERR,有效){
                        如果(ERR){下一个(ERR); }
                        如果(有效){
                            接下来返回(NULL,用户{消息:登录的'});
                        }其他{返回下一个(空,假,{消息:密码不正确}); }
                    });
                }其他{下一个(空,假,{消息:'用户没有激活,请联系管理员。'}); }
            }其他{下一个(空,假,{消息:无法找到与电子邮件用户的电子邮件+}); }
        });
       }
     ));


在控制台中,我总是认为这是成功的。

控制台读取:

 用户登录:{对象姓:约翰,名字:李四,电子邮件:john_doe@work.com,激活:真的,isUser:真的...}

<醇开始=4>

  • 然后,我对发生的事情了解得那种模糊。我知道该应用程序然后试图看到,如果用户被认证。 IsAuthenticated被触发,它看起来像这样在AngularJS:

      isAuthenticated:功能(力){
        变种推迟= $ q.defer();    如果(isAuthenticated&安培;&放大器;的currentUser){
            deferred.resolve(的currentUser);
        }其他{
            返回baseAuth.customGET('验证'),然后(功能(用户){
                deferred.resolve(的currentUser);
                isAuthenticated = TRUE;
                的currentUser =用户;
                返回用户;
            });
        }    返回deferred.promise;
    }


  • 它击中在后端UserController中这个动作

      isAuthenticated:功能(REQ,RES){
       如果(req.isAuthenticated()及&放大器; req.user.isUser){返回res.json(req.user); }
       其他{返回res.send(401); }
    },


  • 然后失败:( GET HTTP://本地主机:1337 /用户/认证401 无论req.isAuthenticated也不req.user.isUser通过我。已经分居出来单独测试和他们都不是真的。isUser是一个值我默认为真,并因此它应该在DB每一个用户是真实的。req.isAuthenticated也失败了,我不完全明白了。

    任何人有一些见解,我的问题?我有什么我做什么错在这里?


    解决方案

    如果您的前端应用有一个不同的产地比你的后端应用程序的 Ajax请求将不包含会话cookie req.isAuthenticated()将永远不会返回true。

    使用的withCredentials选项,迫使它。

      $ HTTP({withCredentials:真实,...})

    似乎Restangular使用相同的选项:

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

    https://docs.angularjs.org/api/ng/service / $#HTTP使用

    编辑:您也应该检查服务器端配置正如idbehold指出


    正如马滩的建议,你应该给一个尝试在服务器端帆生成-auth的生成。

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

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

    I am setting up an authentication functionality for my first time and am getting some unexpected results after a user has been logged in. A colleague has given me an application with working authentication to model my application after and it seems like everything I have done is correct.

    I am using AngularJS on the front-end, SailsJS back-end framework, and PassportJS authentication middleware.

    My source is (for now) stored publicly... the backend API is on Github here (API Github) and the front-end code is found here (Front-End Github)

    What basically happens is that the user

    1. Hits the login button, which triggers this function

      login: function (credentials) {
          return baseAuth.customPOST(credentials, 'login').then(function (user) {
              $log.debug('User logged in: ', user);
              isAuthenticated = true;
              return user;
          });
      },
      

    2. The controller logic for that customPOST is this

      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. In that step, passport should do its thing and login the user

      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 }); }
          });
         }
       ));
      

    In the console, I always get that this is successful.

    Console reads:

    User logged in:  Object {firstName: "John", lastName: "Doe", email: "john_doe@work.com", activated: true, isUser: true…}
    

    1. Then, my understanding of what happens gets kind of fuzzy. I know the application then tries to see if the user is authenticated. IsAuthenticated gets triggered, which looks like this in 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. It hits this action in the backend UserController

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

    Then it fails :( GET http://localhost:1337/user/authenticated 401 (Unauthorized) Neither req.isAuthenticated nor req.user.isUser pass. I have separated them out to individually test and neither of them are true. "isUser" is a value I default to true and is so it should be true for every single user in the db. req.isAuthenticated also fails, which I don't entirely understand.

    Anyone have some insight into my problem? What I have I done wrong here?

    解决方案

    If your frontend application has as a different origin than your backend application the AJAX requests will not include the session cookie and req.isAuthenticated() will never returns true.

    Use the withCredentials options to force it.

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

    It seems that Restangular uses the same options:

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

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

    Edit: You should also check the server side configuration as pointed out by idbehold


    As suggested by Matan, you should really give a try to the sails-generate-auth generator on the server side.

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

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

    这篇关于认证是返回&QUOT; 401&QUOT;当它不应该的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆