我有passport for node的工作知识,但它没有以下内容:
是否有任何库在Node.js社区中解决了这个问题?如果有任何像Devise for Rails那样强大(或者就像它强大的那样),那将是完美的,但解决这个令牌问题的任何东西都可以正常工作。
疯狂的是,很多例子都是在会话中存储用户id
!
request.session['userId'] = user.get('id')
这只是要求被黑客攻击。
它应该是这样的:
require.session['persistenceToken'] = App.User.generateRandomToken()
答案 0 :(得分:8)
密码重置的一次性密码(也就是一次性令牌)策略是我将要实现的。鉴于Passport的架构,这可以很容易地成为一个单独的模块,并且发现其他人已经实现了这样的事情并不会让我感到惊讶。
记住我和持久性令牌功能也是我想支持的。我希望这也是一个单独的策略,但它可能需要一些核心支持。如果事实证明是这种情况,req.logIn
(https://github.com/jaredhanson/passport/blob/master/lib/passport/http/request.js#L28)中的一些额外行应该可以覆盖它。
至于在会话中存储用户ID,我没有看到任何大的风险,默认情况下,在Connect / Express中,会话属性完全存储在后端,并由唯一的sid
查找在加密的cookie中设置。恶意用户必须拥有唯一的sid和会话密钥才能欺骗请求。
Mozilla正在使用Passport作为身份识别工作的一部分,将BrowserID桥接到缺乏BrowserID支持的其他提供商(请参阅browserid-bigtent)。根据他们的要求,开发人员可以确保Passport符合严格的安全要求。
(最终Passport中的会话序列化是应用程序的责任,因此出于安全原因,可以根据需要使用随机令牌代替用户ID。显然,如果将数据直接存储在cookie中,则应该这样做,但我会建议这样做是最不明智的做法。)
至于在模型上管理这些属性,Passport被设计为完全模型/ ORM不可知。我不打算改变这个事实,因为我认为这些决定最好留给应用程序(并且由于委派这个责任,Passport更灵活)。也就是说,我认为其他模块还有空间独立构建在Passport之上以提供此功能。
所有这一切,我认为Passport是现有Node.js auth解决方案中最强大的。你的前三个请求将会有很长的路要走,并且它们应该很容易实现。我很乐意合作获取这些功能,所以不要犹豫与我联系。
最后,如果有人对此感到好奇,那么authinfo分支上的一流API身份验证目前正在进行中。在此基础上,passport-http-oauth实现了OAuth服务器策略,可以与oauthorize middlware结合使用,作为组装OAuth服务器的工具包。这还没有完全出炉,但是当它准备就绪时它将是Passport的另一个有效功能。
答案 1 :(得分:2)
同时,以下内容应该足够了。根据需要进行调整以适合您的应用和所需的Cookie持续时间检查用户名和&密码是一种检测登录尝试的俗气方式,但它在护照上运行良好。
app.use(function(req, res, next) {
if(
typeof(req.body.username) !== "undefined"
&& typeof(req.body.password) !== "undefined"
) {
if(req.body.remember == 1) {
req.session.cookie.maxAge = 365*24*60*60*1000;
}
else {
req.session.cookie.maxAge = 24*60*60*1000;
}
}
next();
});
答案 2 :(得分:2)
虽然我肯定希望在passport.js中看到这些功能,但它们还没有。
我创建了一个简单的随机令牌生成器,用于passport.js serilizeUser()函数,并根据我的需要修改了Justen的答案。基本上,唯一的区别是如果未设置“记住”选项,则只要浏览器打开,会话就会持续。
这是我的随机访问令牌生成器的序列化程序。我正在使用Mongodb和Mongoose,但实现应该很好地转换为其他系统。
基本上,我正在抽出时间并为其添加一个随机的16个字符的字符串。然后,在serializeUser()函数中,我检查没有其他用户具有相同的令牌(令牌应该是唯一的!)。
User.methods.generateRandomToken = function () {
var user = this,
chars = "_!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
token = new Date().getTime() + '_';
for ( var x = 0; x < 16; x++ ) {
var i = Math.floor( Math.random() * 62 );
token += chars.charAt( i );
}
return token;
};
这是序列化器:
passport.serializeUser( function ( user, done ) {
var createAccessToken = function () {
var token = user.generateRandomToken();
app.User.findOne( { accessToken: token }, function (err, existingUser) {
if (err) return done( err );
if (existingUser)
createAccessToken(); // Run the function again - the token has to be unique!
else {
user.set( 'accessToken', token );
user.save( function ( err ) {
if (err) return done( err );
return done( null, user.get('accessToken') );
})
}
});
};
if ( user._id ) {
createAccessToken();
}
});
...这是我处理“记住我”功能的中间件版本。我宁愿以某种方式成为serializeUser函数或passport.js核心的一部分。
app.use( express.session( { secret: 'secret_key' } ) );
app.use( function (req, res, next) {
if ( req.method == 'POST' && req.url == '/login' ) {
if ( req.body.remember ) {
req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days
} else {
req.session.cookie.expires = false;
}
}
next();
});
app.use( passport.initialize() );
app.use( passport.session() );
我希望有所帮助。我花了几个小时来搞清楚,我不太确定这是最好的方式,但它现在对我有用。