我的OTP验证有一个奇怪的问题,OTP应该在2分钟后过期。
生成令牌
var secret = speakeasy.generateSecret({length: 20}).base32;
var token = speakeasy.totp({
secret: secret.base32,
encoding: 'base32',
time:120
});验证令牌
var verified = speakeasy.totp.verify({
secret:req.params.secret,
encoding: 'base32',
token: req.params.token,
time:120
});
console.log(verified);案例-1固定密钥
当我将secret密钥更改为固定密钥(即secret='676FGFG!@$#')时,OTP永远不会过期,console.log(验证);始终返回false
case-2用base32生成密钥
当我使用secret (ie secret = secret.base32)生成base32时,没有验证OTP
Console.log(已验证);始终返回true
发布于 2017-05-11 07:45:57
一个问题是您的秘密实际上被设置为undefined
var secret = speakeasy.generateSecret({length: 20}).base32;
^^^^^^^ notice this
var token = speakeasy.totp({
secret: secret.base32,
^^^^^^^ and again here后者应该是secret : secret,因为secret变量已经包含秘密的Bas-32字符串。
其次,time不是用来设置到期/期限的,这就是step的作用所在。
因为TOTP在特定的时间窗口中是有效的,所以不能(AFAIK)将它们设置为“从现在到将来的5分钟”。您可以做的是调整window值,以便在验证过程中允许宽大处理,在验证过程中,您可以说在5分钟前直到将来的5分钟之间,“属于”时间戳的标记也是有效的:
// creating the token
let token = speakeasy.totp({
...
window : 10
});
// verifying the token:
let verified = speakeasy.verify({
...
window : 10
});默认的step值是30秒,这意味着每30秒生成一个新的令牌。如果您希望该令牌在30秒时间之外仍然验证为“有效”,则可以指定一个窗口。"10“窗口意味着(10 *30秒=) 5分钟前到未来5分钟之间的所有令牌都是有效的。
您也可以将步骤设置为5分钟,但如果用户在5分钟有效期结束时收到令牌,则在令牌失效之前,他们可能只剩下10秒钟。这就是为什么使用更宽的窗口而不是更大的步骤更好的原因。
确保对step和/或window的任何更改都必须同时对speakeasy.totp()和speakeasy.verify()进行。
发布于 2020-03-27 07:56:42
在浪费了4个小时后,这对我是有效的,请复制整个代码,并尝试一次。事后你可以修改它。
Speakeasy.generateSecret({长度:6 });res.send({“秘密”:secret.base32 });
async totpgenerate(request,response) {
response.send({
"token": Speakeasy.time({
secret: request.body.secret,
encoding: "base32",
step:600,//10 mins
window:0
})
})
}
,
async totpvalidate(request,response) {
response.send({
"valid": Speakeasy.time.verify({
secret:request.body.secret,
encoding: 'base32',
token: request.body.token,
step:600,//10 mins
window:0
})
})
}https://stackoverflow.com/questions/43908606
复制相似问题