(进阶篇)PHP(thinkphp5框架)实现用户注册后邮箱验证,激活帐号

本文将结合实例,讲解如何使用thinkphp5+Mysql完成注册帐号、发送激活邮件、验证激活帐号、处理URL链接过期的功能。

业务流程

1、用户提交注册信息。

2、写入数据库,此时帐号状态未激活。

3、将用户名密码或其他标识字符加密构造成激活识别码(你也可以叫激活码)。

4、将构造好的激活识别码组成URL发送到用户提交的邮箱。

5、用户登录邮箱并点击URL,进行激活。

6、验证激活识别码,如果正确则激活帐号。

准备数据表

用户信息表中字段Email很重要,它可以用来验证用户、找回密码、甚至对网站方来说可以用来收集用户信息进行Email营销,以下是用户信息表cmf_email的表结构:

CREATE TABLE `cmf_email`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `email` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `email_password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱注册码',
  `token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '账户激活码',
  `token_exptime` int(10) NULL DEFAULT NULL COMMENT '激活码有效期',
  `status` tinyint(1) NULL DEFAULT 0 COMMENT '状态,0=未激活,1=已激活',
  `regtime` int(10) NULL DEFAULT NULL COMMENT '注册时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '//---前台邮箱注册' ROW_FORMAT = Dynamic;

 

 

 

 

在框架中下载phpmailer包

1.composer require phpmailer/phpmailer

2.在控制器中引入类

use PHPMailer\PHPMailer\PHPMailer

 

 

3步骤 

 

 

<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Powerless < wzxaini9@gmail.com>
// +----------------------------------------------------------------------
namespace app\user\controller;

use cmf\controller\HomeBaseController;
use think\Db;
use think\facade\Validate;
use app\user\model\UserModel;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

class RegisterController extends HomeBaseController
{

    /**
     * 前台用户注册
     */
    public function index()
    {
        return $this->fetch('register');
    }



    //发送qq邮箱
    /*
     * @param
     *  $address_email --收件人邮箱
     *  $active_url ---激活地址
     *  $token --- 账户激活码
     *  $email_password --邮箱密码
     * **/
    public function setEmail($address_email, $token, $active_url, $email_password)
    {
        $sendmail = '135xxx7@qq.com'; //发件人邮箱
        //$sendmailpswd = "cbllxxxxxxxhdbc"; //客户端授权密码,而不是邮箱的登录密码!
        $sendmailpswd = "olbzxxxxhpqjbfc"; //客户端授权密码,而不是邮箱的登录密码!
        $send_name    = '悦桔拉拉商城';// 设置发件人信息,如邮件格式说明中的发件人,
        $toemail      = $address_email;//定义收件人的邮箱
        $to_name      = '小号';//设置收件人信息,如邮件格式说明中的收件人
        $mail         = new PHPMailer();
        $mail->isSMTP();// 使用SMTP服务
        $mail->CharSet    = "utf8";// 编码格式为utf8,不设置编码的话,中文会出现乱码
        $mail->Host       = "smtp.qq.com";// 发送方的SMTP服务器地址
        $mail->SMTPAuth   = true;// 是否使用身份验证
        $mail->Username   = $sendmail; 发送方的
        $mail->Password   = $sendmailpswd;//客户端授权密码,而不是邮箱的登录密码!
        $mail->SMTPSecure = "ssl";// 使用ssl协议方式
        $mail->Port       = 465;//  qq端口465或587)
//        $mail->setFrom($sendmail,$send_name);// 设置发件人信息,如邮件格式说明中的发件人,
        $mail->setFrom($sendmail, $send_name);
        $mail->addAddress($toemail, $to_name);// 设置收件人信息,如邮件格式说明中的收件人,
        $mail->addReplyTo($sendmail, $send_name);// 设置回复人信息,指的是收件人收到邮件后,如果要回复,回复邮件将发送到的邮箱地址
        //$mail->addCC("xxx@qq.com");// 设置邮件抄送人,可以只写地址,上述的设置也可以只写地址(这个人也能收到邮件)
        //$mail->addBCC("xxx@qq.com");// 设置秘密抄送人(这个人也能收到邮件)
        //$mail->addAttachment("bug0.jpg");// 添加附件
        $mail->Subject = "悦桔拉拉商城,激活邮箱";// 邮件标题
//        $mail->Body = "邮件内容是 <b>您的验证码是:123456</b>,哈哈哈!";// 邮件正文
        $mail->Body = "恭喜您,注册成功!请点击链接激活您的帐户:" . "$active_url" . "$token" . "
    如果以上链接无法点击,请将它复制到你的浏览器地址栏中进入访问,该链接24小时内有效。";// 邮件正文
        //$mail->AltBody = "This is the plain text纯文本";// 这个是设置纯文本方式显示的正文内容,如果不支持Html方式,就会用到这个,基本无用
        $token_exptime = time() + 60 * 60 * 24;//过期时间为24小时后
        if (!$mail->send()) {// 发送邮件
            $this->error('邮箱注册失败!请检查邮箱号码是否正确', url('user/register/index'));
        } else {
            //将邮箱与密码写入数据库
            $data = [
                'email'          => $address_email,
                'email_password' => $email_password,
                'token'          => $token,
                'regtime'        => time(),
                'token_exptime'  => $token_exptime,
            ];
            $res  = Db::name('email')->insert($data);
            if ($res) {
                $this->success('恭喜您,注册成功!<br/>请登录到您的邮箱及时激活您的帐号,然后进行登录!', url('user/login/index'));
            }
        }
    }
  
  //前台注册页面,用户点击提交,跳转到控制器里面的add方法
public function add() { if ($this->request->isPost()) { $rules = [ 'email' => $this->request->param('email'), 'email_password' => cmf_password($this->request->param('email_password'), $authCode = 'yjllshop'), ]; $nowtime = time(); //当前时间 //对于是否已经注册用户进行判断 $res = Db('email')->where('email', $rules['email'])->find(); if ($res) { if ($nowtime > $res['token_exptime']) { $this->error('您的激活有效期已过,请登录您的帐号重新发送激活邮件', url('user/register/index')); } else { $this->success('您已经注册过,请直接登录!', url('user/login/index')); } } //dump($rules);die; //激活地址--对应激活方法 $active_url = 'http://www.yjllshop.com/user/register/valRegister?token='; //调用生产token方法 $token = $this->makeToken($rules['email']); $this->setEmail($rules['email'], $token, $active_url, $rules['email_password']); } } //制作token public function makeToken($email) { $regtime = time(); $num = rand(0, 100);//一段随机数字 $md5Num = md5($regtime . $num . $email); $token = base64_encode(md5($md5Num)); //创建用于激活识别码 return $token; } //邮箱激活方法--并且将邮箱的各个信息存放数据库 public function valRegister() { //$token $nowtime = time(); //当前时间 if ($this->request->isGet()) { $token = $this->request->param('token'); //将条件token值与status=0状态值带入数据库查询,如果能查到,在判断时间是够是过期,就进行激活操作,改变激活码 $res = Db('email') ->where('status', 0) ->where('token', $token)->find(); //dump($res); /// dump($res['token_exptime']);die; if ($res) { if ($nowtime > $res['token_exptime']) { $this->error('您的激活有效期已过,请登录您的帐号重新发送激活邮件', url('user/register/index')); } else { Db::name('email')->where('token', $token)->setField('status', 1); $this->success('恭喜您,激活成功!<br/>请进行登录!', url('user/login/index')); } } else { $this->error('邮箱注册失败!请检查邮箱号码是否正确', url('user/register/index')); } } //Db::name('email')->insert($user); } }

  

  

客户端的授权码 

注册完成后的数据库

 

转载于:https://www.cnblogs.com/yehuisir/p/10542282.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用ThinkPHP5实现用户注册、登录、验证的完整代码和数据库设计。 ## 数据库设计 ```sql CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL COMMENT '用户名', `password` varchar(50) DEFAULT NULL COMMENT '密码', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `phone` varchar(20) DEFAULT NULL COMMENT '手机号码', `create_time` int(11) DEFAULT NULL COMMENT '创建时间', `update_time` int(11) DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; ``` ## 注册功能 ### 控制器代码 ```php namespace app\index\controller; use think\Controller; use think\Db; class Register extends Controller { public function index() { if (request()->isPost()) { // 获取表单数据 $data = input('post.'); // 验证用户名 if (empty($data['username'])) { $this->error('用户名不能为空'); } if (Db::name('user')->where('username', $data['username'])->find()) { $this->error('用户名已存在'); } // 验证密码 if (empty($data['password'])) { $this->error('密码不能为空'); } if ($data['password'] != $data['confirm_password']) { $this->error('两次密码输入不一致'); } // 验证邮箱 if (empty($data['email'])) { $this->error('邮箱不能为空'); } if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { $this->error('邮箱格式不正确'); } if (Db::name('user')->where('email', $data['email'])->find()) { $this->error('邮箱已存在'); } // 验证手机号码 if (empty($data['phone'])) { $this->error('手机号码不能为空'); } if (!preg_match('/^1[3456789]\d{9}$/', $data['phone'])) { $this->error('手机号码格式不正确'); } if (Db::name('user')->where('phone', $data['phone'])->find()) { $this->error('手机号码已存在'); } // 添加用户 $user = [ 'username' => $data['username'], 'password' => md5($data['password']), 'email' => $data['email'], 'phone' => $data['phone'], 'create_time' => time(), 'update_time' => time(), ]; if (Db::name('user')->insert($user)) { $this->success('注册成功', 'login/index'); } else { $this->error('注册失败'); } } return $this->fetch(); } } ``` ### 视图代码 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户注册</title> </head> <body> <form method="post"> <div> <label for="username">用户名:</label> <input type="text" name="username" id="username"> </div> <div> <label for="password">密码:</label> <input type="password" name="password" id="password"> </div> <div> <label for="confirm_password">确认密码:</label> <input type="password" name="confirm_password" id="confirm_password"> </div> <div> <label for="email">邮箱:</label> <input type="email" name="email" id="email"> </div> <div> <label for="phone">手机号码:</label> <input type="text" name="phone" id="phone"> </div> <div> <button type="submit">注册</button> </div> </form> </body> </html> ``` ## 登录功能 ### 控制器代码 ```php namespace app\index\controller; use think\Controller; use think\Db; class Login extends Controller { public function index() { if (request()->isPost()) { // 获取表单数据 $data = input('post.'); // 验证用户名和密码 $user = Db::name('user')->where('username', $data['username'])->find(); if (!$user) { $this->error('用户名不存在'); } if (md5($data['password']) != $user['password']) { $this->error('密码不正确'); } // 记录登录状态 session('user', $user); $this->success('登录成功', 'index/index'); } return $this->fetch(); } public function logout() { // 销毁登录状态 session('user', null); $this->success('退出成功', 'login/index'); } } ``` ### 视图代码 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <form method="post"> <div> <label for="username">用户名:</label> <input type="text" name="username" id="username"> </div> <div> <label for="password">密码:</label> <input type="password" name="password" id="password"> </div> <div> <button type="submit">登录</button> </div> </form> </body> </html> ``` ## 验证功能 ### 控制器代码 ```php namespace app\index\controller; use think\Controller; use think\Db; class Verify extends Controller { public function username() { $username = input('get.username'); if (Db::name('user')->where('username', $username)->find()) { return 'false'; } else { return 'true'; } } public function email() { $email = input('get.email'); if (!filter_var($email, FILTER_VALIDATE_EMAIL) || Db::name('user')->where('email', $email)->find()) { return 'false'; } else { return 'true'; } } public function phone() { $phone = input('get.phone'); if (!preg_match('/^1[3456789]\d{9}$/', $phone) || Db::name('user')->where('phone', $phone)->find()) { return 'false'; } else { return 'true'; } } } ``` ### 视图代码 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>验证</title> </head> <body> <script src="/static/js/jquery.min.js"></script> <script> $(function () { $('#username').blur(function () { $.get('/index/verify/username', {username: $(this).val()}, function (data) { if (data == 'true') { $('#username_error').html(''); } else { $('#username_error').html('用户名已存在'); } }); }); $('#email').blur(function () { $.get('/index/verify/email', {email: $(this).val()}, function (data) { if (data == 'true') { $('#email_error').html(''); } else { $('#email_error').html('邮箱已存在或格式不正确'); } }); }); $('#phone').blur(function () { $.get('/index/verify/phone', {phone: $(this).val()}, function (data) { if (data == 'true') { $('#phone_error').html(''); } else { $('#phone_error').html('手机号码已存在或格式不正确'); } }); }); }); </script> <form> <div> <label for="username">用户名:</label> <input type="text" name="username" id="username"> <span id="username_error"></span> </div> <div> <label for="email">邮箱:</label> <input type="email" name="email" id="email"> <span id="email_error"></span> </div> <div> <label for="phone">手机号码:</label> <input type="text" name="phone" id="phone"> <span id="phone_error"></span> </div> </form> </body> </html> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值