varsecret=speakeasy.generateSecret();// Returns an object with secret.ascii, secret.hex, and secret.base32.
// Also returns secret.otpauth_url, which we'll use later.
issuer:可选(强烈推荐),指定服务提供者。这个字段会在 Google Authenticator 客户端中单独显示,在添加了多个服务者提供的 2FA 后特别有用
生成二维码:
1
npm install --save qrcode
1
2
3
4
5
6
7
8
9
10
varQRCode=require('qrcode');// Get the data URL of the authenticator URL
QRCode.toDataURL(secret.otpauth_url,function(err,data_url){console.log(data_url);// Display this data URL to the user in an <img> tag
// Example:
write('<img src="'+data_url+'">');});
// Let's say the user says that the token they have is 132890
varuserToken='132890';// Let's say we stored the user's temporary secret in a user object like above:
// (This is specific to your implementation)
varbase32secret=user.two_factor_temp_secret;// 这个零时的秘钥可以暂时存在用户的temp_secret字段中
// 这里可以读取用户的零时秘钥进行验证如果验证通过删除零时字段存为永久字段比如secret_key
varverified=speakeasy.totp.verify({secret:base32secret,encoding:'base32',token:userToken});
'use strict';constspeakeasy=require('speakeasy');const{Controller}=require('egg');constQRCode=require('qrcode');classHomeControllerextendsController{asyncindex(){// Generate a secret key.
constsecret=speakeasy.generateSecret({length:16});//生成长度是16位的秘钥
console.log(secret);constuser={username:'zhangsan',password:'123456',secret_key:secret.base32,status:1,};constresult2=awaitthis.ctx.model.User.create(user);constgenerateQR=asynctext=>{try{returnawaitQRCode.toDataURL(text);}catch(err){console.error(err);}};constresult=awaitgenerateQR(secret.otpauth_url);// Returns token for the secret at the current time
// Compare this to user input
awaitthis.ctx.render('index',{url:result});}asyncauth(){constcsrf=this.ctx.csrf;awaitthis.ctx.render('auth',{csrf});}asyncdoAuth(){constdata=this.ctx.request.body;constuser=awaitthis.ctx.model.User.findOne();// 验证code
constverified=speakeasy.totp.verify({secret:user.secret_key,encoding:'base32',token:data.code,});// 服务端生成code和google验证器生成的值应该一样
consttoken=speakeasy.totp({secret:user.secret_key,encoding:'base32',});console.log(token);console.log(data.code);console.log(verified);}}module.exports=HomeController;