头图

Node中F2A原理及功能实现总结

导语:之前做过一个小项目,其中用到了F2A(双因素认证)进行登录以及其他的用户身份认证,现在就这个功能的原理以及实现做一个总结。

目录

  • F2A原理
  • 实现方法
  • 实战演练

F2A原理

F2A就是双因素认证的缩写,一种采用时间同步技术的系统,采用了基于时间、事件和密钥三变量而产生的一次性密码来代替传统的静态密码。

大家都知道一般网站验证用户身份都是采用单因素认证,比如:用户名+密码,还有的是手机号+短信验证码。

但是用户+密码的容易被黑客爆破,脱库,撞库进行获取;而短信验证码也容易被伪基站,钓鱼网站,WIFI等手段获取到,从而泄漏用户隐私信息。

今天介绍的这个F2A就是在使用了上述提到的方法外,再另外加一层防护网,对用户登录进行二次验证,验证码是基于用户密钥独立生成的,随机生存的6位数。

而且是在独立的APP专门设备上面存放,只有你自己可以查看,而且这个验证码是60秒切换一次,每次都不一样,加大了黑客破解的时间难度。

实现方法

继续打开上次的demo文件夹,然后创建一个f2a文件夹,写入一个文件index.js

这次要实现的功能包括以下几点:

  • 生成二维码功能;
  • 生成F2A密钥
  • 验证F2A密码

生成二维码功能

这个功能比较简单,安装一个qrcode就可以了。

$ npm install qrcode --save
const express = require('express');
const app = express();
const qrcode = require('qrcode');

app.get('/f2a/qrcode', (req, res) => {
    let url = req.query.url;
    if (!url) {
        return res.json({
            code: 101,
            msg: 'get_fail',
            data: {
                info: "url不能为空!"
            }
        });
    }
    qrcode.toDataURL(url, (err, data) => {
        return res.send('<img src="' + data + '">');
    })
})

打开游览器,随便输入一个网址参数,来测试一下。

这里使用百度一下:http://localhost:3000/f2a/qrcode?url=https://www.baidu.com/

这里是预览截图:

在这里插入图片描述

生成F2A密钥

接下来就是今天的主角登场,F2A双因素。

先来下载一个依赖包,安装一下引入文件。

$ npm install speakeasy --save

获取F2A

这里主要使用generateSecret来创建F2A密钥信息;

const express = require('express');
const app = express();
const speakeasy = require('speakeasy');

app.get('/f2a', (req, res) => {
    let secret = speakeasy.generateSecret({length: 20});
    return res.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) => {
    let token = req.body.code;
    let secret = req.body.secret;
    if (!token) {
        return res.json({
            code: 101,
            msg: 'get_fail',
            data: {
                info: "验证码不能为空!"
            }
        });
    }
    if (!(/^\d{6}$/.test(token))) {
        return res.json({
            code: 101,
            msg: 'get_fail',
            data: {
                info: "验证码格式不正确!"
            }
        });
    }
    if (!secret) {
        return res.json({
            code: 101,
            msg: 'get_fail',
            data: {
                info: "密钥不能为空!"
            }
        });
    }
    let verifyInfo = {
        secret,
        encoding: 'base32',
        token,
    }

    let verify = speakeasy.totp.verify(verifyInfo);
    if (verify) {
        return res.json({
            code: 200,
            msg: 'get_succ',
            data: {
                info: "验证成功!"
            }
        });
    } else {
        return res.json({
            code: 101,
            msg: 'get_fail',
            data: {
                info: "验证失败!"
            }
        });
    }

})

其实这个依赖包还有个生成随机六位数的方法。

app.get('/code', (req, res) => {
    let secret = req.query.secret;
    if (!secret) {
        return res.json({
            code: 101,
            msg: 'get_fail',
            data: {
                info: "密钥不能为空!"
            }
        });
    }

    var token = speakeasy.totp({
        secret,
        encoding: 'base32'
    });

    return res.json({
        code: 200,
        msg: 'get_succ',
        data: {
            info: "获取成功!",
            code: token,
        }
    });

})

打开http://localhost:3000/f2a/code?secret=F44T62DGOJJT66TLH5WGWVBQJ47XUZJO,会出现一个六位数,这个就是生成的,大约有60秒有限期。

在这里插入图片描述

这个code里面的六位数其实和F2A应用的六位数是等效的,一样的,你也可以使用这个方法做一个类似的小程序,扫码绑定,显示六位数,这也是可以的。

实战演练

现在F2A的功能基本上是实现了,但是想要体验一下,你必须准备好F2A应用才可以。

这里推荐三个比较常用F2A应用:

在这里插入图片描述

  • 微信小程序:二次验证码

在这里插入图片描述

有了应用后,

绑定F2A

先打开那个网址,由于是get请求,直接在游览器打开,获取到密钥和地址。

在这里插入图片描述

现在已经出来了,

  • 密钥是secret的值:F44T62DGOJJT66TLH5WGWVBQJ47XUZJO,
  • 地址是url的值:otpauth://totp/SecretKey?secret=F44T62DGOJJT66TLH5WGWVBQJ47XUZJO

接下来有两种方法绑定:

  • 直接在F2A应用输入secret里面;
  • 扫描二维码更方便(省去输入环节);

接下来采用第二种方法。

在游览器打开http://localhost:3000/f2a/qrcode?url=otpauth://totp/SecretKey?secret=F44T62DGOJJT66TLH5WGWVBQJ47XUZJO,看到一个二维码,使用F2A应用扫描后,成功绑定。

在这里插入图片描述

在这里插入图片描述

F2A验证

这次使用postman进行验证,打开postman软件,输入url以及参数。

点击发送按钮,可以如下图,验证成功。

在这里插入图片描述

以上就是使用node实现F2A功能的一个基本的使用方法总结。

Talk is cheap, show me the code.

48 声望
1 粉丝
0 条评论
推荐阅读
测速工具使用心得体会
导语:之前写过一个测速小工具,使用的是speedtest-cli提供的api方法,当然除了这个还有其他的测速工具,今天就这个测速工具来说一下使用体验和感受。

MarkGuan阅读 531

封面图
从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木75阅读 7.1k评论 16

从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木45阅读 8.5k评论 6

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木35阅读 6.7k评论 10

从零搭建 Node.js 企业级 Web 服务器(五):数据库访问
回顾 从零搭建 Node.js 企业级 Web 服务器(一):接口与分层,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,控制层与服务层实现了业务处理过程,模型层定义了业务实体并以 对象-关系...

乌柏木34阅读 5k评论 9

2022大前端总结和2023就业分析
我在年前给掘金平台分享了《2022年热点技术盘点》的前端热点,算是系统性的梳理了一下我自己对前端一整年的总结。年后,在知乎上看到《前端的就业行情怎么样?》,下面都是各种唱衰前端的论调,什么裁员,外包化...

i5ting27阅读 2.3k评论 4

封面图
从零搭建 Node.js 企业级 Web 服务器(十三):断点调试与性能分析
Node.js 官方提供了断点调试机制,出于安全性考虑默认为关闭状态,可以通过 node 参数 --inspect 或 --inspect-brk 开启,配合 IDE 能够非常方便地调试代码,本章就上一章已完成的项目 licg9999/nodejs-server-ex...

乌柏木31阅读 4.2k评论 9

Talk is cheap, show me the code.

48 声望
1 粉丝
宣传栏