认证是返回" 401"当它不应该 [英] Authentication is returning "401 (Unauthorized)" when it shouldn't
问题描述
我建立了我的第一次认证功能和我得到一些意想不到的结果,用户已被记录后,一位同事给我的应用程序一起工作的认证后,我的应用模式,它看起来像我的一切做的是正确的。
我使用的前端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:真的...}
<醇开始=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
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
这篇关于认证是返回&QUOT; 401&QUOT;当它不应该的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!