下面我将详细介绍如何使用ThinkPHP框架实现短信验证注册功能,包括数据库设计、短信发送、验证码验证等完整流程。
1. 数据库设计
首先创建用户表和短信验证码表:
-- 用户表CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `mobile` varchar(20) NOT NULL COMMENT '手机号', `password` varchar(255) NOT NULL COMMENT '密码', `nickname` varchar(50) DEFAULT NULL COMMENT '昵称', `status` tinyint(1) DEFAULT '1' COMMENT '状态(1:正常,0:禁用)', `create_time` int(11) DEFAULT NULL COMMENT '创建时间', `update_time` int(11) DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `mobile` (`mobile`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';-- 短信验证码表CREATE TABLE `sms_code` ( `id` int(11) NOT NULL AUTO_INCREMENT, `mobile` varchar(20) NOT NULL COMMENT '手机号', `code` varchar(10) NOT NULL COMMENT '验证码', `create_time` int(11) NOT NULL COMMENT '创建时间', `expire_time` int(11) NOT NULL COMMENT '过期时间', `ip` varchar(50) DEFAULT NULL COMMENT 'IP地址', `status` tinyint(1) DEFAULT '0' COMMENT '状态(0:未使用,1:已使用)', PRIMARY KEY (`id`), KEY `mobile` (`mobile`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信验证码表';
2. 创建模型
创建用户模型和短信验证码模型:
// application/index/model/User.phpnamespace app\index\model;use think\Model;class User extends Model{ // 设置当前模型对应的完整数据表名称 protected $table = 'user'; // 自动时间戳 protected $autoWriteTimestamp = true; // 密码加密 public function setPasswordAttr($value) { return password_hash($value, PASSWORD_DEFAULT); }}// application/index/model/SmsCode.phpnamespace app\index\model;use think\Model;class SmsCode extends Model{ // 设置当前模型对应的完整数据表名称 protected $table = 'sms_code'; // 自动时间戳 protected $autoWriteTimestamp = 'create_time';}
3. 短信服务类
创建短信服务类,这里以阿里云短信为例:
// application/common/service/SmsService.phpnamespace app\common\service;use think\facade\Config;class SmsService{ // 发送短信验证码 public static function sendCode($mobile, $code) { // 这里替换为你的阿里云短信配置 $config = Config::get('aliyun_sms'); $params = [ 'PhoneNumbers' => $mobile, 'SignName' => $config['sign_name'], 'TemplateCode' => $config['template_code'], 'TemplateParam' => json_encode(['code' => $code]) ]; // 调用阿里云短信接口 try { $result = self::sendSms($params); return $result; } catch (\Exception $e) { return false; } } // 阿里云短信发送方法 private static function sendSms($params) { // 这里实现阿里云短信发送逻辑 // 实际项目中应该使用阿里云官方SDK // 模拟发送成功 return true; }}
4. 控制器实现
创建注册控制器:
// application/index/controller/Register.phpnamespace app\index\controller;use think\Controller;use think\facade\Config;use think\facade\Request;use app\index\model\User;use app\index\model\SmsCode;use app\common\service\SmsService;class Register extends Controller{ // 发送短信验证码 public function sendCode() { $mobile = Request::param('mobile'); // 验证手机号格式 if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) { return json(['code' => 0, 'msg' => '手机号格式不正确']); } // 检查手机号是否已注册 if (User::where('mobile', $mobile)->find()) { return json(['code' => 0, 'msg' => '该手机号已注册']); } // 生成验证码 $code = mt_rand(100000, 999999); // 保存验证码到数据库 $smsData = [ 'mobile' => $mobile, 'code' => $code, 'expire_time' => time() + 300, // 5分钟后过期 'ip' => Request::ip() ]; SmsCode::create($smsData); // 发送短信 if (SmsService::sendCode($mobile, $code)) { return json(['code' => 1, 'msg' => '验证码发送成功']); } else { return json(['code' => 0, 'msg' => '验证码发送失败']); } } // 用户注册 public function doRegister() { $data = Request::param(); // 验证数据 $validate = new \app\index\validate\Register; if (!$validate->check($data)) { return json(['code' => 0, 'msg' => $validate->getError()]); } // 验证短信验证码 $smsCode = SmsCode::where([ 'mobile' => $data['mobile'], 'code' => $data['code'], 'status' => 0 ])->order('id', 'desc')->find(); if (!$smsCode) { return json(['code' => 0, 'msg' => '验证码错误']); } if ($smsCode->expire_time < time()) { return json(['code' => 0, 'msg' => '验证码已过期']); } // 创建用户 $userData = [ 'mobile' => $data['mobile'], 'password' => $data['password'], 'nickname' => '用户_' . substr($data['mobile'], -4) ]; $user = User::create($userData); if ($user) { // 标记验证码为已使用 $smsCode->status = 1; $smsCode->save(); return json(['code' => 1, 'msg' => '注册成功']); } else { return json(['code' => 0, 'msg' => '注册失败']); } }}
5. 验证器
创建注册验证器:
// application/index/validate/Register.phpnamespace app\index\validate;use think\Validate;class Register extends Validate{ protected $rule = [ 'mobile' => 'require|mobile', 'password' => 'require|length:6,20', 'code' => 'require|length:6', ]; protected $message = [ 'mobile.require' => '手机号不能为空', 'mobile.mobile' => '手机号格式不正确', 'password.require' => '密码不能为空', 'password.length' => '密码长度6-20位', 'code.require' => '验证码不能为空', 'code.length' => '验证码长度6位', ]; // 自定义手机号验证规则 protected function mobile($value) { return preg_match('/^1[3-9]\d{9}$/', $value) ? true : false; }}
6. 前端页面
创建注册页面(使用jQuery):
<!-- application/index/view/register/index.html --><!DOCTYPE html><html><head> <meta charset="utf-8"> <title>用户注册</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script></head><body> <h1>用户注册</h1> <form id="registerForm"> <div> <label>手机号:</label> <input type="text" name="mobile" placeholder="请输入手机号"> <button type="button" id="sendCodeBtn">获取验证码</button> </div> <div> <label>验证码:</label> <input type="text" name="code" placeholder="请输入验证码"> </div> <div> <label>密码:</label> <input type="password" name="password" placeholder="请输入密码"> </div> <div> <button type="submit">注册</button> </div> </form> <script> $(function() { // 发送验证码 $('#sendCodeBtn').click(function() { var mobile = $('input[name="mobile"]').val(); if (!/^1[3-9]\d{9}$/.test(mobile)) { alert('手机号格式不正确'); return; } $(this).attr('disabled', true); $.post('{:url("register/sendCode")}', {mobile: mobile}, function(res) { if (res.code == 1) { alert('验证码发送成功'); // 倒计时 var countdown = 60; var timer = setInterval(function() { countdown--; $('#sendCodeBtn').text(countdown + '秒后重新获取'); if (countdown <= 0) { clearInterval(timer); $('#sendCodeBtn').text('获取验证码').attr('disabled', false); } }, 1000); } else { alert(res.msg); $('#sendCodeBtn').attr('disabled', false); } }, 'json'); }); // 注册提交 $('#registerForm').submit(function(e) { e.preventDefault(); var formData = $(this).serialize(); $.post('{:url("register/doRegister")}', formData, function(res) { if (res.code == 1) { alert('注册成功'); window.location.href = '{:url("index/index")}'; } else { alert(res.msg); } }, 'json'); }); }); </script></body></html>
7. 路由配置
在路由配置文件中添加路由:
// route/route.phpuse think\facade\Route;Route::get('register', 'index/register/index');Route::post('register/sendCode', 'index/register/sendCode');Route::post('register/doRegister', 'index/register/doRegister');
8. 配置阿里云短信
在配置文件中添加阿里云短信配置:
// config/aliyun_sms.phpreturn [ 'access_key_id' => 'your_access_key_id', 'access_secret' => 'your_access_secret', 'sign_name' => 'your_sign_name', 'template_code' => 'your_template_code', 'region_id' => 'cn-hangzhou'];
9. 完整流程说明
用户访问注册页面,输入手机号
点击获取验证码按钮,前端发送AJAX请求到
/register/sendCode
后端验证手机号格式和是否已注册
生成6位随机验证码并保存到数据库
调用阿里云短信接口发送验证码
用户输入验证码和密码提交注册
后端验证验证码是否正确和是否过期
验证通过后创建用户账号
标记验证码为已使用状态
返回注册成功信息
10. 安全注意事项
验证码有效期:设置合理的有效期(通常5-10分钟)
验证码使用限制:每个验证码只能使用一次
IP限制:限制同一IP的发送频率
手机号限制:限制同一手机号的发送频率
密码加密:使用password_hash加密存储密码
防XSS攻击:对用户输入进行过滤
防CSRF攻击:添加CSRF令牌验证
以上就是一个完整的ThinkPHP短信验证注册功能的实现方案,你可以根据实际需求进行调整和扩展。
希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。