目录
1.效果展示
2.发送验证码
3.进行验证
以绑定邮箱为例,注册验证的话修改判断逻辑
1.效果展示
2.发送验证码
/**
* 发点击验证
* 参数 email
*/
public function sendClick(){
$param = $this->request->post();
// 邮箱email的validate规则验证,略...
$user = $this->auth->getUser();
// 防抖
$key = md5('send_click'.json_encode($param));
$lock = Cache::get($key);
if ($lock){
$this->error('请勿频繁请求');
}
Cache::set($key, 1, 60);
// 邮箱是否已被占用
$find = User::where(['email' => $param['email']])
->where('id', '<>', $user['id'])
->find();
if($find){
$this->error('该邮箱已被其他账号绑定');
}
// 发送邮件
$from = '我的name';
$arr['subject'] = '【'.$from.'】请查收你的验证信息';
$url = request()->domain();
$content = json_encode([
'url' => $url,
'user_id' => $user->id,
'email' => $param['email'],
'time' => time(),
]);
// url中的+号需要转义为%2B,否则无法正确识别,并进行常规的AES加解密
$params = urlencode(Aes::encrypt($content));
$url = $url.'/xxx/click_verify/check/?params='.$params;
// 格式化邮箱的确认页面
$arr['message'] = $this->clickHtml($url);
$obj = new Email();
$result = $obj
->from('自己的邮箱地址', $from)
->to($param['email'])
->subject($arr['subject'])
->message($arr['message'])
->send();
if (!$result) {
return false;
}
if ($ret) {
$this->success(__('发送成功'));
} else {
$this->error(__('发送失败,请检查短信配置是否正确'));
}
}
/**
* @param $url
* @return string
* 点击验证
*/
public function clickHtml($url)
{
return <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电子邮件验证</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f7f7f7;
padding: 20px;
text-align: center;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
p {
line-height: 1.5;
color: #4a4a4a;
text-align: center;
}
a {
display: inline-block;
padding: 10px 15px;
border-radius: 5px;
color: blue;
text-decoration: none;
margin-top: 30px;
text-align: center;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<h1>电子邮件验证</h1>
<p>感谢您在我们的网站上注册认证!请单击以下链接验证您的电子邮件地址:</p>
<p style="color: blue">{$url}</p>
</body>
</html>
HTML;
}
- aes加密参考:【PHP】openssl_encrypt、openssl_decrypt对称加密解密-CSDN博客
3.进行验证
public function check()
{
$param = $this->request->get('params');
// 对参数进行验证
$ret = $this->encry($param);
if($ret['code'] == 0){
$this->error($ret['msg']);
}
$array = $ret['array'];
Db::startTrans();
try {
$user = User::where(['id' => $array['user_id']])->find();
if($user['is_auth_email'] == 1){
throw new \Exception('该账号已经认证邮箱,无需重复操作');
}
$user->is_auth_email = 1;
$user->email = $array['email'];
Creditscorelog::package($user, 'email_auth');
$user->save();
Db::commit();
} catch (\Exception $e) {
$this->error('验证失败:'.$e->getMessage());
}
$url = request()->domain();
$this->success('验证成功', $url);
}
// 以下是验证的方法
protected $noNeedUrl = ['www.taskpublish.com', 'www.52qzl.com'];
/**
* 验证
*/
public function encry($param= []){
if(empty($param)){
return ['code' => 0,'msg' => '参数错误,验证失败'];
}
$domain = $_SERVER['HTTP_HOST'];
if(!in_array($domain, $this->noNeedUrl)){
return ['code' => 0,'msg' => '域名不在白名单中,验证失败'];
}
try {
$ret = Aes::decrypt($param);
} catch (\Exception $e) {
return ['code' => 0,'msg' => $e->getMessage()];
}
$array = json_decode($ret, true);
if(empty($array)){
return ['code' => 0,'msg' => '参数错误,验证失败'];
}
if(time() - $array['time'] > 120){
return ['code' => 0,'msg' => '验证超时,请重新发送'];
}
// 邮箱唯一性验证
$find = User::where(['email' => $array['email']])
->where('id', '<>', $array['user_id'])
->find();
if($find){
return ['code' => 0,'msg' => '该邮箱已被其他账号绑定'];
}
return ['code' => 1,'array' => $array];
}