PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集

QQ:420220301 微信/手机:150-3210-7690
当前位置:首页 > 工作总结

Thinkphp实现短信验证注册功能

管理员 2025-03-26
工作总结
91

下面我将详细介绍如何使用ThinkPHP框架实现短信验证注册功能,包括数据库设计、短信发送、验证码验证等完整流程。

1. 数据库设计

首先创建用户表和短信验证码表:

sql
复制
-- 用户表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. 创建模型

创建用户模型和短信验证码模型:

php
复制
// 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. 短信服务类

创建短信服务类,这里以阿里云短信为例:

php
复制
// 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. 控制器实现

创建注册控制器:

php
复制
// 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. 验证器

创建注册验证器:

php
复制
// 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):

html
复制
<!-- 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. 路由配置

在路由配置文件中添加路由:

php
复制
// 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. 配置阿里云短信

在配置文件中添加阿里云短信配置:

php
复制
// 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. 完整流程说明

  1. 用户访问注册页面,输入手机号

  2. 点击获取验证码按钮,前端发送AJAX请求到/register/sendCode

  3. 后端验证手机号格式和是否已注册

  4. 生成6位随机验证码并保存到数据库

  5. 调用阿里云短信接口发送验证码

  6. 用户输入验证码和密码提交注册

  7. 后端验证验证码是否正确和是否过期

  8. 验证通过后创建用户账号

  9. 标记验证码为已使用状态

  10. 返回注册成功信息

10. 安全注意事项

  1. 验证码有效期:设置合理的有效期(通常5-10分钟)

  2. 验证码使用限制:每个验证码只能使用一次

  3. IP限制:限制同一IP的发送频率

  4. 手机号限制:限制同一手机号的发送频率

  5. 密码加密:使用password_hash加密存储密码

  6. 防XSS攻击:对用户输入进行过滤

  7. 防CSRF攻击:添加CSRF令牌验证

以上就是一个完整的ThinkPHP短信验证注册功能的实现方案,你可以根据实际需求进行调整和扩展。




希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。

相关推荐

扫码关注

qrcode

QQ交谈

回顶部