无密码身份验证:安全、简单且部署快速(加载身份验证密码)

网友投稿 857 2022-08-29

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

无密码身份验证:安全、简单且部署快速(加载身份验证密码)

Passwordless authentication: Secure, simple, and fast to deploy

然而,大多数网站仍在使用最早期的 web 身份验证方式:用户名与密码。

Passwordless 入门非常简单。两个小时以内,你就能学会部署全面且安全的身份验证解决方案:

$ npm install passwordless --save

$ npm install passwordless-mongostore --save

在传送令牌给用户时,电子邮件通常是最好的选择(不过,短消息也可以)。你可以任意选择邮件框架,比如:

$ npm install emailjs --save

基本设置

var passwordless = require('passwordless'); var MongoStore = require('passwordless-mongostore'); var email = require("emailjs");

var smtpServer = email.server.connect({ user: yourEmail, password: yourPwd, host: yourSmtp, ssl: true});

最后的一个预备步骤是告知 Passwordless 你选择了哪一种存储接口,并将之初始化:

传递令牌

deliver 在调用时,需要全部的细节信息。因此,令牌的传递(在本例中,使用的是 emailjs)如下所示,相当简单:

初始化 Express 中间件

app.use(passwordless.sessionSupport()); app.use(passwordless.acceptToken({ successRedirect: '/'}));

路径选择与身份验证

你至少需要两个 URLs,从而:- 展示用于获取用户邮箱地址的页面- 获取表格细节(通过 POST 方法)

/* GET: login screen */router.get('/login', function(req, res) { res.render('login');});

/* POST: login details */router.post('/sendtoken', function(req, res, next) { // TODO: Input validation }, // Turn the email address into a user ID passwordless.requestToken( function(user, delivery, callback) { // E.g. if you have a User model: User.findUser(email, function(error, user) { if(error) { callback(error.toString()); } else if(user) { // return the user ID to Passwordless callback(null, user.id); } else { // If the user couldn’t be found: Create it! // You can also implement a dedicated route // to e.g. capture more user details User.createUser(email, '', '', function(error, user) { if(error) { callback(error.toString()); } else { callback(null, user.id); } }) } }) }), function(req, res) { // Success! Tell your users that their token is on its way res.render('sent');});

此处有何猫腻?passwordless.requestToken(getUserId) 的任务有二:第一、确保邮箱地址真实存在。第二、将该地址转变为独一无二的用户 ID,通过邮件一并发送,并在之后用于验证用户身份。通常,你都有一套存储用户细节信息的模型,你可以按照上例的说明,进行简单的设置。

在一些情况下(例如,由两个用户编辑过的博客),你可以跳过用户模型,将他们有效的邮箱地址与其各自的 ID 相联系:

var users = [ { id: 1, email: 'marc@example.com' }, { id: 2, email: 'alice@example.com' }];/* POST: login details */router.post('/sendtoken', passwordless.requestToken( function(user, delivery, callback) { for (var i = users.length - 1; i >= 0; i--) { if(users[i].email === user.toLowerCase()) { return callback(null, users[i].id); } } callback(null, null); }), // Same as above…

HTML 页面

本例只需要一个简单的 HTML 页面,用以获取用户的邮箱地址。默认情况下,Passwordless 会查找 user 输入栏中的内容:

Login

Email:

保护网页

Passwordless 提供了能确保只有验证用户才能看到指定页面的中间件:

/* Protect a single page */router.get('/restricted', passwordless.restricted(), function(req, res) { // render the secret page});/* Protect a path with all its children */router.use('/admin', passwordless.restricted());

谁处于登录状态?

默认情况下,Passwordless 允许通过请求对象 req.user 获取用户 ID。想要展示或重用此 ID,或从数据库中得到更多细节信息,你可以这么实现:

router.get('/admin', passwordless.restricted(), function(req, res) { res.render('admin', { user: req.user });});

或者,更一般化地,你可以添加另一个中间件,从模型中抽取出某个用户的全部记录,再将其分配给网站中的任意路径:

app.use(function(req, res, next) { if(req.user) { User.findById(req.user, function(error, user) { res.locals.user = user; next(); }); } else { next(); }})

到此为止啦!

点评

如前所示,所有的身份验证系统都有其优缺点。你应该按照自己的需求进行合理的选择。基于令牌的验证方式,与绝大多数解决方法(包括经典的用户名/密码方法)一样,都存在一个风险:如果用户的邮箱账户被盗用,并且/或者 SMTP 服务器与用户的连接被入侵,用户在网站的账户就会随之遭到盗用。默认情况下,有两种办法可以减弱该风险(但不是完全避免):短时间有效的令牌以及令牌在使用后自动失效。

对大多数网站而言,基于令牌的身份验证方法代表着走向安全的进步:用户无需再想新的密码(这些密码往往非常简单),也不存在用户重用密码的风险。对于身为开发者的我们,Passwordless 提供了唯一一种(且相当简单的)身份验证解决方案,该方案易于理解,因此容易保护。此外,我们也无需再处理用户的密码了。

另一个值得讨论的点是可用性。我们应该同时考虑两种情况:用户在网站的首次使用以及后续的登录。对首次用户而言,基于令牌的身份验证非常直观:与经典的登录机制一样,他们还是不得不验证邮箱地址。但是,在最佳案例中,除此之外就不需要其他细节信息了。不需要再煞费苦心地想一个符合所有限制条件的密码,也不需要刻意记住密码。如果用户再次登录,其体验与特定的用户案例有关。大多数网站的会话有效期都很长,因而不需要再次登录。或者,用户访问该网站的频率其实非常低,以致于他们想不起来自己是否已经拥有账户,或者忘记了账户密码。在这种情况下,Passwordless 在可用性方面的优势相当明显。同样地,这需要经历不多的几个步骤,解释起来也非常简单。然而,那些用户访问频繁的网站,以及/或那些要求用户一周内手动登录几次的网站(比如 Amazon),经典的身份验证(或更保险地:双重验证)或许更加适合。因为用户很可能会真的记住他们的密码,并且意识到好密码的重要性。

上一篇:「事件管理」如何让用户体验更加极致?(举例如何将用户体验做到极致)
下一篇:ASP .NET 如何在 SQL 查询层面实现分页(阿司匹林)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~