认证是返回" 401"当它不应该不应、当它、QUOT

2023-09-13 03:04:37 作者:姐的美无可挑剔

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

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

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

基本上什么情况是,用户

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

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

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

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

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

  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:真的...} 

然后,我对发生的事情了解得那种模糊。我知道该应用程序然后试图看到,如果用户被认证。 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

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

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

},

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…}

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

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