Node.js 使用哪种护照身份验证
我在我的网站上使用了几种Passport身份验证策略,效果很好,但是,我需要一种Node.js 使用哪种护照身份验证,node.js,passport.js,Node.js,Passport.js,我在我的网站上使用了几种Passport身份验证策略,效果很好,但是,我需要一种Demo或(我们可以称之为session)策略,它根据用户的会话id自动授权用户,现在我正在手动执行,当用户导航到/Demo页面时,我在db(mongodb)上运行一个查询,使用会话id,如果用户存在,我将使用该用户呈现页面,如果不存在,我将创建一个 app.get('/demo', function(req,res) { db.User.findOne({ 'accounts.kind': 'demo', 'a
Demo
或(我们可以称之为session
)策略,它根据用户的会话id自动授权用户,现在我正在手动执行,当用户导航到/Demo
页面时,我在db(mongodb)上运行一个查询,使用会话id,如果用户存在,我将使用该用户呈现页面,如果不存在,我将创建一个
app.get('/demo', function(req,res) {
db.User.findOne({ 'accounts.kind': 'demo', 'accounts.sid': req.sessionID }, function(err, user) {
if (user) {
res.render( 'home', {
user: user
});
} else {
var user = new db.User();
user.accounts.push({
kind: 'demo',
sid: req.sessionID,
created: Date.now
});
req.session.userId = user._id;
user.save(function(err) {
if(err) { throw err; }
res.render( 'home', {
user: user
});
});
}
});
});
用户架构如下所示:
UserSchema = new Schema({
uname: {type: String},
accounts: [],
docs:[{type:Schema.Types.ObjectId, ref:'Doc'}]
})
它可以工作,但我需要设置一个会话变量,因为此方法不登录用户,我的意思是请求中没有req.user
,但通过该会话变量,我可以检查用户是否是演示用户
if (req.user) {
userid = req.user._id.toString();
} else {
userid = req.session.userId;
}
我相信有一种更优雅的方式可以做到这一点,使用现有的passport策略之一。我看到有,和,还有其他几个,但我不确定我应该用哪一个
为用户创建数据库条目对我来说很重要。因此,稍后我可以附加另一个帐户。请从中查看第4节。这是将会话id放入cookie并在用户返回时检索数据的代码。不需要战略
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
我可以这样解决: 确定了新的战略,
var passport = require('passport')
, util = require('util');
function DemoStrategy(options, verify) {
if (typeof options == 'function') {
verify = options;
options = {};
}
if (!verify) throw new Error('Demo Basic authentication strategy requires a verify function');
passport.Strategy.call(this);
this.name = 'demo';
this._verify = verify;
}
util.inherits(DemoStrategy, passport.Strategy);
DemoStrategy.prototype.authenticate = function(req) {
var self = this;
this._verify( req, function(err, user) {
if (err) { return self.error(err); }
self.success(user);
});
}
module.exports.Strategy = DemoStrategy;
路线:
app.get('/auth/demo',
passport.authenticate('demo'),
function(req,res) {
res.redirect('/');
}
);
和护照。使用部分:
passport.use(new DemoStrategy(
function(req, done) {
console.log( 'using demo strategy, req: ', req );
if (req.user) {
// place code here, if we want to attach to an existing account
} else {
db.User.findOne({ 'accounts.kind': 'demo', 'accounts.sid': req.sessionID }, function(err, dbuser) {
if (dbuser) {
done(null,dbuser);
} else {
var user = new db.User();
user.accounts.push({
kind: 'demo',
sid: req.sessionID,
created: Date.now
});
user.save(function(err) {
if(err) { throw err; }
done(null,user);
});
}
});
}
}
));
也许它充满了bug,错误处理还没有完成,但似乎是正确的解决方案,它集成到了备受赞赏的库中,事实证明,在这种情况下,创建自定义策略是不必要的。我发现该官员有一个(未记录的)
passReqToCallback
选项,允许您在verify函数中访问req
对象。您可以使用它来使用LocalStrategy执行各种操作,只需更改verify函数:
passport.use(new LocalStrategy({
passReqToCallback: true
}, function(req, username, password, done) {
//now that you have req object, you can
//probably do whatever you need to do right here
});
请注意,该函数现在接受4个参数req、username、password、done
,从req
对象开始,而不是默认的3个参数
我希望这能为您节省一些时间,在阅读LocalStrategy代码之前,我花了一个小时试图解决这个问题。这对cookie不起作用吗?@Patrick是的,它涉及cookie,会话id在cookie中,那么您就不需要策略了。序列化和反序列化应该会自动工作,并在用户返回时检索会话。我有这些函数,但它们是由passport.session()中间件调用的(如果我是对的),当我使用演示身份验证时,passport会被完全跳过。按设计:)最后我创建了一个新策略,请参见下面(或上面)的Hmm,好的。对不起,我没听清楚。不,不,对我问题的描述很弱。感谢您的时间,我还是从您的回答中学到了一些东西。请注意:其他策略也有此选项。我已经在使用LocalStrategy,我认为它不能被使用两次。实际上,您可以多次使用它,您只需在passport配置中为它命名,如:
passport.use('other-login',new LocalStrategy())然后在路由中:app.post('/otherlogin',passport.authenticate('other-login')代码>。没有名字,LocalStrategy的默认名称为“local”,这真的是使用会话信息对用户进行身份验证的最佳方式,这样他们就不必重新输入用户名/密码吗?在我的例子中,这是一个临时用户(尝试演示用户),可以转换为完全注册的用户。我使用了许多passport身份验证策略,因此它非常适合我的应用程序。