Strapi v4能否实现手机号验证码登录认证功能?
Strapi v4 手机号+短信验证码登录实现方案
当然可以实现,Strapi v4的扩展性完全支持手机号+短信验证码登录的需求,以下是具体实现思路和步骤:
1. 扩展用户模型
首先需要在默认的用户模型中添加手机号字段,确保手机号唯一且必填:
在src/api/user/content-types/user/schema.json中添加字段配置:
{ "attributes": { "phone": { "type": "string", "unique": true, "required": true, "minLength": 11, "maxLength": 11 } } }
修改后重启Strapi,即可在用户管理面板中看到手机号字段。
2. 创建验证码管理模型
新建一个VerificationCode内容类型,用于存储验证码和过期时间,字段包括:
phone:字符串类型,关联用户手机号code:字符串类型,存储6位验证码expiresAt:日期时间类型,设置验证码过期时间(比如5分钟)
3. 编写自定义认证服务
在src/api/auth/services/auth.js中实现验证码生成、发送、验证逻辑:
'use strict'; module.exports = ({ strapi }) => ({ // 生成6位随机验证码 generateCode() { return Math.floor(100000 + Math.random() * 900000).toString(); }, // 发送短信验证码(需替换为实际短信服务商API调用) async sendSmsCode(phone) { const code = this.generateCode(); // 示例:调用第三方短信接口发送验证码 // await strapi.service('plugin::sms.send')(phone, `您的登录验证码是${code},5分钟内有效`); // 保存验证码到数据库 await strapi.db.query('api::verification-code.verification-code').create({ data: { phone, code, expiresAt: new Date(Date.now() + 5 * 60 * 1000) } }); return { success: true, message: '验证码已发送' }; }, // 验证验证码并生成登录令牌 async verifyCode(phone, code) { // 查询有效验证码 const validCode = await strapi.db.query('api::verification-code.verification-code').findOne({ where: { phone, code, expiresAt: { $gt: new Date() } } }); if (!validCode) { throw new Error('验证码无效或已过期'); } // 验证通过后删除验证码,防止重复使用 await strapi.db.query('api::verification-code.verification-code').delete({ where: { id: validCode.id } }); // 查询对应用户 const user = await strapi.db.query('plugin::users-permissions.user').findOne({ where: { phone } }); if (!user) { throw new Error('该手机号未注册'); } // 生成Strapi标准JWT令牌 const jwtToken = strapi.plugins['users-permissions'].services.jwt.issue({ id: user.id }); return { success: true, user, jwt: jwtToken }; } });
4. 配置自定义路由
在src/api/auth/routes/auth.js中添加两个公开路由:
'use strict'; module.exports = { routes: [ { method: 'POST', path: '/auth/send-sms-code', handler: 'auth.sendSmsCode', config: { auth: false } }, { method: 'POST', path: '/auth/login-with-sms', handler: 'auth.verifyCode', config: { auth: false } } ] };
5. 权限配置
在Strapi后台的「设置-权限」中,将上述两个自定义路由的权限设置为「公开」,确保未登录用户可以访问。
6. 前端对接流程
- 用户输入手机号,前端调用
POST /auth/send-sms-code接口,传入手机号 - 用户收到短信后输入验证码,前端调用
POST /auth/login-with-sms接口,传入手机号和验证码 - 接口返回JWT令牌后,前端将令牌存入本地存储,后续请求携带
Authorization: Bearer {token}头即可完成认证
额外注意事项
- 短信服务商API需自行集成,可封装为Strapi插件提升复用性
- 高并发场景建议用Redis替代数据库存储验证码,提升性能
- 可添加限流逻辑,限制同一手机号的验证码发送频率,防止恶意刷取短信
内容的提问来源于stack exchange,提问作者varimax
相关产品推荐
相关产品推荐

