在日常开发过程中,我们会经常遇到用邮箱找回密码,今天就给大家讲解一下。
一、设置思路
1、用户注册时需要提供一个 email 邮箱,目的就是用该邮箱找回密码。
2、当用户忘记密码或用户名时,点击登录页面的“找回密码”超链接,打开表单,并输入注册用的 email 邮箱,提交。
3、系统通过该邮箱,从数据库中查找到该用户信息,并更新该用户的密码为一个临时密码(比如:123456)。
4、系统借助 PHPMailer 类库把该用户的信息发送到该用户的邮箱中(内容包括:用户名、临时密码、提醒用户及时修改临时密码的提示语)。
5、用户用临时密码即可登录。
二、HTML页面
在找回密码的页面上放置一个要求用户输入注册时所用的邮箱,然后提交,由 js 来完成和后台的交互。
代码如下:
<p><strong>输入您注册的电子邮箱,找回密码:</strong></p>
<p><input type="text" class="input" name="email" id="email"> <span id="chkmsg"></span></p>
<p id="sucmsg"></p>
<p><input type="button" class="btn" id="sub_btn" value="提交"></p>
三、jQuery请求与交互
当用户输入完邮箱并点击提交后,js 先验证邮箱格式是否正确,若正确则向 sendemail.php 发送 Ajax 请求,sendemail.php 会验证邮箱是否存在和发送邮件,并将相应的处理结果返回给前台页面,并在页面展示其结果。
js 代码如下
<script>
$(function(){
$("#sub_btn").click(function(){
var email = $("#email").val();
//匹配email
var preg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
if(email=='' || !preg.test(email)){
$("#chkmsg").html("请填写正确的邮箱!");
}else{
$.post("sendemail.php",{mail:email},function(msg){
if(msg=="no"){
$("#chkmsg").html("该邮箱尚未注册!");
$("#sub_btn").removeAttr("disabled").val('提 交').css("cursor","pointer");
}else{
$("#sucmsg").html("<b>"+msg+"</b>");
}
});
}
});
})
</script>
注意:要在页面中加载JQuery库文件,否则无法使用。
四、PHP 文件
1、sendemail.php 需要验证 Email 是否存在系统用户表中,如果有,则读取用户信息,将用户id、用户名和密码进行 md5 加密后生成一个字符串作为找回密码的token,之后构造URL。
同时我们为了控制URL链接的时效性,将记录用户提交找回密码的时间,最后调用邮件发送方法发送邮件到用户邮箱,发送邮件方法 smtp.func.php 已经打包好。代码如下:
<?php
// 连接数据库
include_once 'connect.php';
// 获取ajax提交的邮箱
$email = stripslashes(trim($_POST['mail']));
$sql = "SELECT user_id,username,password FROM `t_user` WHERE `email`='$email'";
$query = mysqli_query($db,$sql);
$rows = mysqli_num_rows($query);
if($rows == 0){
echo 'no'; // 邮箱未注册
exit;
} else {
// 获取用户信息
$userinfo = mysqli_fetch_assoc($query);
$uid = $userinfo['user_id'];
$resettime = time();
// 组合验证
$token = md5($uid.$userinfo['username'].$userinfo['password']);
// 构造url
$url = 'reset.php?email='.$email.'&token='.$token;
// 发送邮件时间
$sendtime = date('Y-m-d H:i:s',time());
$result = sendemail($email,$url,$sendtime);
if($result == 'success'){ // 邮件发送成功
$msg = '系统已向您的邮箱发送了一封邮件<br/>请登录到您的邮箱及时重置您的密码!';
// 更新邮件发送时间
$sql = "UPDATE `t_user` SET `resettime`=$resettime WHERE `user_id`=$uid";
mysqli_query($db,$sql);
} else {
$msg = $result;
}
echo $msg;
}
/**
* 发送邮件
* @param string $email 用户提交的邮箱
* @param string $url url
* @param string $time 发送邮件的时间
* @return string 邮件发送的结果信息
*/
function sendemail($email,$url,$time){
include_once("smtp.func.php");
$emailfrom = 'welcome_liu@163.com'; // 发件人的邮箱
$emailto = $email; // 收件人的邮箱
$emailtype = "HTML"; //信件类型,文本:text;网页:HTML
// 邮件主题
$emailsubject = "找回密码";
// 邮件内容
$emailbody = "用户,您好:<br/>您在".$time."提交了找回密码请求。请点击下面的链接重置密码
(按钮24小时内有效)。<br/><a href='".$url."'target='_blank'>".$url."</a>";
$rs = sendMail($emailfrom, $emailto, $emailtype, $emailsubject, $emailbody);
return $rs;
}
点击提交之后,你的邮箱将会收到一封的密码找回邮件,邮件内容中有一个URL链接,点击该链接到 reset.php 来验证邮箱。
reset.php 代码:
<?php
include_once 'connect.php';
$email = stripcslashes(trim($_GET['email']));
$token = stripcslashes(trim($_GET['token']));
$sql = "SELECT * FROM `t_user` WHERE `email`='$email'";
$query = mysqli_query($db,$sql);
$row = mysqli_fetch_assoc($query);
if($row){
$temp = md5($row['user_id'].$row['username'].$user['password']);
if($temp == $token){
if(time()-$row['resettime']>24*60*60){
$msg = '链接已超时,请重新发送邮件!';
} else {
$msg = '可以重置密码,具体实现就不介绍了';
}
} else {
$msg = 'token错误,链接无效';
}
} else {
$msg = '错误链接';
}
echo $msg;
reset.php 首先接受两个参数 email和token,然后根据 email 查询数据表 t_user 中是否存在该 email。
若 email 存在则获取该用户的信息,并且和 sendmail.php 中的 token 组合方式一样生成 token 值,然后再与 url 传过来的 token 进行对比,若token值不相同,则提示“该链接无效,token值错误!”;若当前时间与发送邮件时的时间相差超过24小时,则提示“该链接已超时!”。
反之,则说明链接有效,并且调转到重置密码页面,这时用户就可以自己设置新密码了。
最后,附上数据表t_user结构:
CREATE TABLE `t_user` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL COMMENT '用户名',
`password` varchar(255) NOT NULL COMMENT '用户密码',
`email` varchar(255) NOT NULL COMMENT '邮箱',
`resettime` int(11) DEFAULT NULL COMMENT '重置密码的时间',
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
smtp.func.php文件
<?php
include_once 'mailer/PHPMailer.php';
include_once 'mailer/SMTP.php';
include_once 'mailer/Exception.php';
/**
* 发送邮件(163邮箱)
*/
function sendMail($from,$to,$type,$subject,$body)
{
$mail = new mailer\PHPMailer(true);
try {
//服务器设置
$mail->CharSet ="UTF-8"; //设定邮件编码
$mail->SMTPDebug = 0; // 调试模式输出
$mail->isSMTP(); // 使用SMTP
$mail->Host = 'smtp.163.com';// SMTP服务器
$mail->SMTPAuth = true;// 允许 SMTP 认证
// SMTP 用户名 即邮箱的用户名
$mail->Username = 'welcome_liu@163.com';
// 授权码 不是邮箱的登录密码
$mail->Password = 'IQYXGUJRKOLHOCZK';
$mail->SMTPSecure = 'ssl';// 允许 TLS 或者ssl协议
// 服务器端口 25 或者465 具体要看邮箱服务器支持
$mail->Port = 465;
$mail->setFrom($from); //发送人邮箱
$mail->addAddress($to); // 收件人邮箱
// 是否以HTML文档格式发送 发送后客户端可直接显示对应HTML内容
$mail->isHTML($type);
// 设置邮件内容
$mail->Subject = $subject; // 主题
$mail->Body = $body; // 内容
$mail->send();
return 'success';
} catch (Exception $e) {
return "发送失败. 失败原因: {$mail->ErrorInfo}";
}
}
connect.php 文件代码:
<?php
// 连接数据库
$db = mysqli_connect('127.0.0.1','root','123456','test');