(进阶篇)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); } }
客户端的授权码
注册完成后的数据库