护照本地临时密码(首次登录时更改)
出于安全原因,我们创建用户并向其发送临时生成的密码。在继续导航受保护页面之前,用户首次登录时应更改其密码。护照本地临时密码(首次登录时更改)
我正在使用运行护照本地模块的快递/节点网站。注册,登录用户全部工作。但是我有点迷失在用户在第一次登录时更改密码的最佳做法。
我的想法是做到以下几点:
/* POST login page. */
router.post('/login', function(req, res, next) {
passport.authenticate('local', { successRedirect: '/dashboard/users',
failureRedirect: 'pages/login'}, function(err, user, info) {
if(err) {
console.log('')
return res.render('pages/login', {title: 'Login', error: err.message});
}
if(!user) {
return res.render('pages/login', {title: 'Login', error: info.message});
}
return req.logIn(user, function(err) {
if(err) {
return res.render('pages/login', {title: 'Login', error: err.message});
} else if (user.firstLogin) {
return res.redirect('/change-password'); // <- First login
} else {
return res.redirect('/dashboard/users');
}
});
})(req, res, next);
});
正如你可以看到我有一个简单的布尔(TINYINT 0-1)在我的数据库设置(默认为1)。之后我会设置一个post方法,在成功修改之后,布尔值将被设置为0.
这是一个正确的方法('a'而不是'':p)?安全性如何?
肯定是a正确的方法。我会说它非常适合你的需求。我个人喜欢数据库字段的用法如何直接反映它背后的业务逻辑。
替代品,虽然我是你的解决方案的风扇,可以是:
添加lastLogin
日期字段到您的数据库默认为NULL
。这会在用户登录时存储日期时间标记。如果用户曾经登录过,则可以将其用作隐式检查。我个人更喜欢为他们的目的有明确的列(比如你正在处理你的firstLogin
列),因为应用程序的列和业务逻辑的目的非常明确。
另一种方法是存储,当用户有最近更新他的密码即lastPasswordChange
默认为NULL
为新用户。与上述相同的推理。如果您希望您的用户每天更改密码,可能会很有用。
安全性说我会说这是坚实的。只要您的firstLogin
字段默认为1
,那么在首次登录时,新用户将无法跳过密码更改。
然而,当用户更新自己的密码,请务必在同一个查询或执行事务中两个查询更新该firstLogin
领域。通过这种方式,您将始终确保密码和firstLogin
字段已更改。如果由于某种原因,任何一个查询都会失败,您将有一个用户已经更改了密码,并被要求/强制再次更改密码,或者拥有随机生成密码的用户不要求更改密码。 在相同的查询中执行此操作将确保两者都一致,或两者都不会同时更新。在事务内部执行操作时,您可以选择在任一查询失败时选择失败/回滚事务。
在另一方面,你的代码可以这样写的(包括你的路,这是正确的,它只是一个偏好和视觉的物质):
/* POST login page. */
router.post('/login', function(req, res, next) {
passport.authenticate('local', {
successRedirect: '/dashboard/users',
failureRedirect: 'pages/login'
}, function(err, user, info) {
if(err) {
console.log('')
return res.render('pages/login', {title: 'Login', error: err.message});
}
if(!user) {
return res.render('pages/login', {title: 'Login', error: info.message});
}
return req.logIn(user, function(err) {
if(err) {
return res.render('pages/login', {title: 'Login', error: err.message});
}
// Using if/else if/else makes no difference since if the first if is executed
// in both cases nothing else will execute due to if/else or the return.
// In case the above statement resolves to `false` the effect wills till be the same
if (user.firstLogin) {
return res.redirect('/change-password'); // <- First login
}
// The else is not necessary due to the return in the line above.
return res.redirect('/dashboard/users');
});
})(req, res, next);
});
如果您想更具体的答案要么问题,我需要一个更具体的问题。
将“检查首次登录”逻辑移动到单独的中间件中执行所有“登录路由”可能是一件好事。
根据上面的建议,用户可以简单地在重定向后离开/更改密码?
我不介意用户离开页面,但只要他想再次登录:他将被再次要求更改密码。我可能会记录整个情况来检查这一点。 – Goowik
对不起,迟到的接受。谢谢你的回复,帮助我很多。 – Goowik