本文简要介绍下通过otpauth库实现otp一次性密码二次验证
本文仅展示TOTP简单的实现方案,HOTP较为复杂也需要服务端支持,详细文档可查阅npm地址
本库不仅支持浏览器环境也支持文档中提及的One Time Password (HOTP/TOTP) library for Node.js, Deno, Bun and browsers.
代码案例
import { Secret, TOTP, URI } from 'otpauth';
//创建订阅地址
const getUri = ()=>{
const secret = new Secret({ size: 20 }); //生成加密密钥(一个账户生成一次)
console.log('唯一的签证密钥----', secret);
const totp = new TOTP({
issuer: '村行门户', // 与帐户关联的提供商或服务。
label: 'admin', // 帐户标识符。
algorithm: 'SHA1',// HMAC 函数使用的算法。
digits: 6, // 生成的令牌的长度。
period: 45,// 令牌有效的时间间隔,以秒为单位。
secret: secret, // 或 'OTPAuth.Secret.fromBase32("NB2W45DFOIZA")' // 以 Base32 或 OTPAuth.Secret 实例编码的任意密钥。
});
const uri = totp.toString(); //获取订阅地址(一个账户生成一次)
console.log('订阅地址----', uri);
//生成订阅地址后进行二维码生成在FreeOtp软件中扫描订阅
}
//校验动态验证码
const validateToken = (val,uri) => { //val为输入的验证码,uri为订阅地址
const totpParams = URI.parse(uri); //反向解析创建TOTP实例使用
const totp = new TOTP(totpParams);
console.log('解析订阅地址----', totpParams);
const nowDate = Date.now(); //当前系统时间时间戳该系统时间为避免用户本地时间不准确建议获取服务器地址
console.log('当前系统时间----', new Date(nowDate));
let token = totp.generate({ timestamp: nowDate }); //获取当前验证码
console.log('指定时间戳获取令牌----', token);
const delta = totp.validate({ token: '验证码', window: 1, timestamp: nowDate }); //校验验证码
console.log('指定时间戳校验令牌----', delta); // 0 为成功
console.log('==============================================');
};