最近在搞otp,让小伙伴们在登录个别应用时使用。可扫码添加OTP账号的手机app有谷歌的authenticator,微软的authenticator和红帽的FreeOTP。不过安卓手机可能找不到官方渠道下载这些靠谱的app,于是又手写了一个显示动态口令的网页,方便用户访问网页就可以看到自己当前的动态口令。
这里有个小坑跟大家分享一下。因为有用户的密钥,所以可以随时生成当前的动态口令,由于是30秒一变,如果不能确切知道变化的时刻,那么如果想要显示在网页上的动态口令和服务器生成的动态口令同步,误差不超过1秒的话,每秒查询一次最多可能要查29次才能确定变化时间,而这些otp的app里的显示的当前动态口令的有效时间倒计数却很准,难道是在密钥里就包含了动态口令的变化时间么?我看了下npm模块里otp的源码,发现并没有这个莫须有的变化时间信息。再打印动态口令变化时间才发现端倪,原来就是标准时间的每分钟的0秒或者30秒切换,自己看来的确是想多了。网页上的显示呈现也就很简单了。
var count;
var firstlook;
var clockid;
function redraw(){
showstat(count);
$("#countdown").html(30-count);
if ((count==0)||(firstlook)) {
axios.get('/querytoken').then(res=> {
$("#curtoken").html(res.data.token)
firstlook=false;
}).catch(err => { console.log(err); alert("OTP服务错"); });
}
count=(count+1) % 30;
}
...
count=(new Date).getSeconds()%30;
firstlook=true; redraw();
clockid=setInterval(redraw,1000);