什么是 OTP 验证码
OTP(One-Time Password)即一次性密码,是一种基于时间或事件的动态密码,一旦被使用后,就会失效。OTP 可以增加账户的安全性,常见的应用场景有:电子银行、电商支付、VPN 连接等。
对于前端开发者而言,实现 OTP 验证码功能需要做到以下几点:
- 生成随机且唯一的验证码
- 将验证码保存到服务端
- 对用户提交的验证码进行验证
- 验证码只能使用一次
本文将使用 Koa.js 实现 OTP 验证码功能。
生成随机且唯一的验证码
生成随机数的方法有很多种,本文将使用 crypto 模块生成随机字符串。crypto.randomBytes()
函数可以生成指定长度的 Buffer,通过将其转为字符串后返回即可。
const crypto = require('crypto'); function generateOTP(len = 6) { return crypto.randomBytes(len).toString('base64').replace(/\+/g, '0').replace(/\//g, '0'); }
在上述代码中,len
参数表示验证码长度,默认为 6。crypto.randomBytes()
返回的 Buffer 可能包含 +
或 /
,需替换为其它字符才能直接作为文本使用。
将验证码保存到服务端
我们可以使用 Redis 或数据库将生成的验证码保存到服务端,本文将使用 Redis。
// javascriptcn.com 代码示例 const redis = require('redis'); const client = redis.createClient(); async function saveOTP(phone, otp) { await client.set(`OTP:${phone}`, otp); await client.expire(`OTP:${phone}`, 60); // 验证码有效期为 60 秒 } async function getOTP(phone) { return new Promise((resolve, reject) => { client.get(`OTP:${phone}`, (err, reply) => { if (err) { reject(err); } else { resolve(reply); } }); }); }
上述代码中,saveOTP()
函数用于保存验证码,getOTP()
函数用于获取验证码。代码中将存储的键值对前缀为 OTP:
,防止与其它键冲突,数据格式为 {phone number}:{one-time-password}
。
对用户提交的验证码进行验证
通过与服务端保存的验证码比对,实现验证码验证功能。本文将使用以下路由实现验证码发送和验证功能:
// javascriptcn.com 代码示例 const Koa = require('koa'); const bodyParser = require('koa-bodyparser'); const app = new Koa(); app.use(bodyParser()); app.use(async (ctx) => { const { phone, otp } = ctx.request.body; if (otp) { const savedOTP = await getOTP(phone); if (savedOTP === otp) { ctx.body = '验证成功'; } else { ctx.body = '验证码错误'; } } else { const newOTP = generateOTP(); await saveOTP(phone, newOTP); ctx.body = '验证码已发送'; } }); app.listen(3000, () => { console.log('Server running at http://localhost:3000'); });
将服务端地址设置为 http://localhost:3000
,通过发送 POST 请求来发送或验证验证码。请求体中应包含 phone
参数。
验证码只能使用一次
为了防止验证码被多次使用,我们可以将验证码的有效期设为一个较短的时间,一旦被使用就将其从 Redis 中删除。
// javascriptcn.com 代码示例 async function deleteOTP(phone) { await client.del(`OTP:${phone}`); } if (savedOTP === otp) { await deleteOTP(phone); ctx.body = '验证成功'; } else { ctx.body = '验证码错误'; }
总结
本文使用 Koa.js 和 Redis 实现了 OTP 验证码功能,并解决了验证码随机性、存储、验证和使用一次的问题。这个功能可以用于增强网站或应用程序的安全性,避免用户账户被恶意攻击。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654e9da17d4982a6eb7bdd08