【PHP】一个邮箱点击验证的完整示例

news2024/11/25 14:59:56

目录

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];
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1319657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

酒精壁炉,现代取暖的便携选择

酒精壁炉作为现代室内取暖的一种选择&#xff0c;具有独特的特点和工作原理。酒精壁炉采用酒精作为燃料&#xff0c;为家庭提供舒适的温暖&#xff0c;同时具备一定的安全性和便携性。 酒精壁炉通常由金属或陶瓷制成&#xff0c;内部设有专门的燃烧器&#xff0c;用于燃烧酒精燃…

SpringBoot使用@DS配置 多数据源 【mybatisplus druid datasource mysql】

项目最近需要使用多数据源&#xff0c;不同的mapper分别读取不同的链接&#xff0c;本项目使用了mybatisplus druid 来配置多数据源&#xff0c;基于mysql数据库。 目录 1.引入依赖 ​2.配置文件 application.yaml 3.Mapper中使用DS切换数据源 4.使用DS的注意事项 1.引入依…

用uniapp写一个点击左侧可以滑动的menu

完成后的图片&#xff08;点击左侧右边或滑动&#xff0c;滑动右边左侧的选中也会变化&#xff09;&#xff1a; 数据js &#xff08;classifyData&#xff09;&#xff1a; export default[{"name": "女装","foods": [{"name": &q…

ansible(不能交互)

1、定义 基于python开发的一个配置管理和应用部署工具&#xff0c;在自动化运维中异军突起&#xff0c;类似于xshell一键输入的工具&#xff0c;不需要每次都切换主机进行操作&#xff0c;只要有一台ansible的固定主机&#xff0c;就可以实现所有节点的操作。不需要agent客户端…

[足式机器人]Part4 南科大高等机器人控制课 Ch08 Rigid Body Dynamics

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;CLEAR_LAB 笔者带更新-运动学 课程主讲教师&#xff1a; Prof. Wei Zhang 南科大高等机器人控制课 Ch08 Rigid Body Dynamics 1. Spatial Vecocity1.1 Spatial vs. Conventional Accel1.2 Plueker Coordinate System and…

二叉树的最大深度(LeetCode 104)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一&#xff1a;深度优先搜索GolangC 方法二&#xff1a;广度优先搜索GolangC 参考文献 1.问题描述 给定一个二叉树 root &#xff0c;返回其最大深度。 叉树的「最大深度」是指从根节点到最远叶子节点的最长路径上的节…

会旋转的树,你见过吗?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;强烈推荐优质专栏: &#x1f354;&#x1f35f;&#x1f32f;C的世界(持续更新中) &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;…

精选暖心的早安问候语图片,送一份温馨问候、送一串真诚祝福!

1、寒天催日短&#xff0c;风浪与云平;大雪随风降&#xff0c;祝福与您行;降温总无情&#xff0c;问候暖身心;短信虽礼轻&#xff0c;礼轻情意重!冬季渐深&#xff0c;温度渐冷&#xff0c;注意身体&#xff0c;健康养生!早上好&#xff01; ​ 2、问候是明亮的灯塔&#xff0…

第二证券:激发资本市场数智新动能 实现高质量发展

12月15日至16日&#xff0c;深交所与港交所、广期所联合举行主题为“科技引领数智赋能”的2023年大湾区生意所科技大会。 本次大会深化贯彻落实中心经济作业会议精神和中心金融作业会议精神&#xff0c;聚焦工作数字化转型和科技立异前沿趋势&#xff0c;深化粤港澳大湾区协同…

C语言文件权限

前言 提笔不会忘字的人&#xff0c;提键盘却忘了编程语言&#xff0c;差点忘本了&#xff0c;用python&#xff0c;shell等脚本语言忘记C语言怎么用了&#xff0c;研究文件系统简单的文件读写不会写了&#xff0c;记录一下。 简单的文件读写 #include <unistd.h> #inc…

快猫视频模板源码定制开发 苹果CMS 可打包成双端APP

苹果CMS快猫视频网站模板源码&#xff0c;可用于开发双端APP&#xff0c;后台支持自定义参数&#xff0c;包括会员升级页面、视频、演员、专题、收藏和会员系统等完整模块。还可以直接指定某个分类下的视频为免费专区&#xff0c;具备完善的卡密支付体系&#xff0c;无需人工管…

Apipost检测接口工具的基本使用方法

&#x1f440; 今天言简意赅的介绍一款和postman一样好用的后端接口测试工具Apipost 专门用于测试后端接口的工具&#xff0c;可以生成接口使用文档官方下载网站&#xff1a;http://www.apipost.cn 傻瓜式安装—>register->项目->创建项目->APIs->新建目录&…

Spring Boot 3 + Vue 3 整合 WebSocket (STOMP协议) 实现广播和点对点实时消息

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

CTF竞赛密码学题目解析

CTF&#xff08;Capture The Flag&#xff09;竞赛是一个有趣的挑战。密码学是CTF竞赛中的核心元素之一&#xff0c;通常涉及解密、破译密码、理解加密算法等技能。以下是30个题目及答案&#xff0c;新入行的可以看看鸭。 题目及答案 1. Caesar Cipher 描述&#xff1a;给出一…

MinHash-LSH:如何解决医学大模型的大规模数据去重?

MinHash-LSH 最小哈希 局部敏感哈希&#xff1a;如何解决医学大模型的大规模数据去重&#xff1f; 大模型的数据问题MinHash-LSH 最小哈希 局部敏感哈希&#xff1a;大规模数据集去重优化Jaccard相似度&#xff1a;用于比较样本集之间的相似性降维技术 MinhashLSH – 局部敏感…

SCC-Tarjan算法,强连通分量算法,从dfs到Tarjan详解

文章目录 前言定义强连通强连通分量 Tarjan算法原理及实现概念引入搜索树有向边的分类强连通分量的根时间戳追溯值 算法原理从深搜到TarjanTarjan算法流程Tarjan算法代码实现 OJ练习&#xff1a; 前言 强连通分量是图论中的一个重要概念&#xff0c;它在许多领域都有广泛的应用…

Qt之使用QListView加载相册(富文本ToolTip)

一.效果 二.实现 #include "mainwindow.h" #include "ui_mainwindow.h"#include <QStandardItemModel> #include <QFont>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);QFont…

SourceTree 免登录跳过初始设置

用于Windows和Mac的免费Git客户端。 Sourcetree简化了如何与Git存储库进行交互&#xff0c;这样您就可以集中精力编写代码。通过Sourcetree的简单Git GUI可视化和管理存储库。 SourceTree 安装之后需要使用账号登陆以授权&#xff0c;以前是可以不登陆的&#xff0c;但是现在是…

基于ssm办公自动化管理系统论文

摘 要 随着计算机应用的普及、成熟&#xff0c;越来越多公司开始采用网上信息管理系统&#xff0c;网上信息管理系统的运行可以有效的提高企业管理效率。因此&#xff0c;为满足企业办公管理方面的需求&#xff0c;开发了办公自动化管理系统。 本文重点阐述了办公自动化管理系…

c语言:输出1~100的数据以10×10格式

一、题目 以10*10的格式&#xff0c;输出1-100。 如图&#xff1a; 二、思路分析 此题的难点&#xff1a; 1、1-9的要向前空一格&#xff1b; 2、100要向前进一格 三、代码截图【带注释】 四、源代码【带注释】 #include <stdio.h> int main() { //分成三个部分&am…