简介:之前做过一个小项目,使用F2A(双因素认证)进行登录等用户认证。下面我就这个功能的原理和实现做一个总结。目录F2A原理实现方法PracticalexerciseF2A原理F2A是two-factorauthentication的缩写,一种采用时间同步技术的系统,使用基于时间、事件和密钥三个变量生成的一次性密码来代替传统的静态密码。大家都知道一般的网站都是采用单因素认证来验证用户身份,比如:用户名+密码,手机号+短信验证码。但用户+密码容易被黑客爆破,短信验证码也容易被假基站、钓鱼网站、WIFI等方式获取,从而泄露用户隐私信息。今天介绍的F2A就是利用上面提到的方法,再多加一层防护网,对用户登录进行二次验证。验证码是根据用户密钥独立生成的,是一个随机的6位数字。并且保存在独立的APP专用设备上,只有自己可以查看,验证码每60秒切换一次,每次都不一样,增加了黑客破解的时间和难度。实现方法继续上次打开demo文件夹,然后新建一个f2a文件夹,写一个文件index.js。本次要实现的功能包括以下几点:生成二维码功能;生成F2A密钥验证F2A密码生成二维码。这个功能比较简单,安装一个二维码就可以了。$npminstallqrcode--saveconstexpress=require('express');constapp=express();const二维码=require('二维码');app.get('/f2a/qrcode',(req,res)=>{leturl=req.query.url;if(!url){returnres.json({code:101,msg:'get_fail',data:{info:"url不能为空!"}});}qrcode.toDataURL(url,(err,data)=>{returnres.send('');})})打开浏览器,输入任意URL参数,进行测试。这里用百度:http://localhost:3000/f2a/qrcode?url=https://www.baidu.com/。下面是预览截图:生成F2A密钥接下来就是今天的主角登场了,F2A双因子。首先下载一个依赖包,安装导入文件。$npminstallspeakeasy--save获取F2A这里generateSecret主要用于创建F2A密钥信息;constexpress=require('快递');constapp=express();constspeakeasy=require('speakeasy');app.get('/f2a',(req,res)=>{letsecret=speakeasy.generateSecret({length:20});returnres.json({code:200,msg:'get_succ',data:{info:'获取成功',secret:secret.base32,url:secret.otpauth_url,}});})其中secret是你的个人密钥,url是你的F2A设备要扫描的地址。接下来看看浏览器中的效果。验证F2A密码这里主要使用totp.verify方法验证六位数字是否正确。app.post('/f2a',(req,res)=>{lettoken=req.body.code;letsecret=req.body.secret;if(!token){returnres.json({code:101,msg:'get_fail',data:{info:"验证码不能为空!"}});}if(!(/^\d{6}$/.test(token))){returnres.json({code:101,msg:'get_fail',data:{info:"验证码格式不正确!"}});}if(!secret){returnres.json({code:101,msg:'get_fail',data:{info:"密钥不能为空!"}});}letverifyInfo={secret,encoding:'base32',token,}letverify=speakeasy.totp.verify(verifyInfo);if(verify){returnres.json({code:200,msg:'get_succ',data:{info:"验证成功!"}});}else{returnres.json({code:101,msg:'get_fail',data:{info:"验证失败!"}});}})其实这个依赖包还有生成随机六位数的方法app.get('/code',(req,res)=>{letsecret=req.query.secret;if(!secret){returnres.json({code:101,msg:'get_fail',data:{info:"密钥不能为空!"}});}vartoken=speakeasy.totp({secret,encoding:'base32'});returnres.json({code:200,msg:'get_succ',data:{info:"获取成功!",code:token,}});})打开http://localhost:3000/f2a/code?secret=F44T62DGOJJT66TLH5WGWVBQJ47XUZJO,会出现一个六位数字,这个是生成的,大约60秒限时。此代码中的六位数字实际上与F2A申请中的六位数字相同。同样的,你也可以用这个方法制作一个类似的小程序,扫码绑定,显示六位数字。这也是可能的。.实战演练现在基本实现了F2A的功能,但是想要体验的话还得准备F2A的应用。下面介绍三个常用的F2A应用:authy微信小程序:二次验证码应用后,绑定F2A先打开网址。既然是get请求,直接在浏览器打开,获取key和地址。现在出来了,key是secret的值:F44T62DGOJJT66TLH5WGWVBQJ47XUZJO,地址是url的值:otpauth://totp/SecretKey?secret=F44T62DGOJJT66TLH5WGWVBQJ47XUZJO接下来有两种绑定方式:直接在F2A申请;扫描两个二维码更方便(省略输入链接);接下来采用第二种方法。在浏览器中打开http://localhost:3000/f2a/qrcode?url=otpauth://totp/SecretKey?secret=F44T62DGOJJT66TLH5WGWVBQJ47XUZJO,看到一个二维码,用F2Aapp扫描,绑定成功。F2A验证这次使用postman验证,打开postman软件,输入url和参数。点击发送按钮,如下图,验证成功。以上就是对如何使用node实现F2A功能的一个基本总结。