node+mysql实现(账户密码,阿里云短信验证,QQ邮箱注册登录,短信验证密码重置,邮箱密码重置)之注册,登录密码重置总篇

news2024/9/24 1:23:42

node+mysql实现账户登录

    • 注意
      • 效果图
      • 项目插件
      • 代码参数说明
        • 短信验证模块
        • 邮箱验证模块
        • 注册方式
        • 登录方式
        • 密码重置
      • 前端页面部分
        • 登录页面
          • 账户登录页面(login.html)
          • 短信验证登录页面(smsLogin.html)
          • 邮箱登录页面(emailLogin.html)
        • 注册部分页面
          • 短信验证注册页面(register.html)
          • 邮箱验证注册(emailRegister.html)
        • 密码重置部分页面
          • 短信验证密码重置(restPassword.html)
          • 邮箱验证密码重置(emailRest.html)
      • js部分
        • 数据库连接db.js
        • SQL语句部分(db/account.js)
        • 路由下的js部分(router/*)
          • account.js
          • api.js
          • email.js
      • app.js
        • MySQL

注意

项目中所用到的验证码模块都不是虚拟的,手机号短信验证调用的是阿里云的短信服务模块,QQ邮箱验证码是调用邮件服务模块

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目插件

layui ,layui消息通知插件(notify)

//Express
npm install express
//body-parser
npm install body-parser
//阿里云相关短信服务
npm install @alicloud/dysmsapi20170525
npm install @alicloud/openapi-client
npm install @alicloud/tea-util
//mysql2
npm install mysql2
//邮件
npm install nodemailer

代码参数说明

短信验证模块

在这里插入图片描述

邮箱验证模块

在这里插入图片描述

注册方式

在这里插入图片描述

登录方式

在这里插入图片描述

密码重置

在这里插入图片描述

前端页面部分

登录页面
账户登录页面(login.html)

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>暖意书栈登录</title>
  <!-- 设置系统图标 -->
   <link rel="shortcut icon" href="../icon/login.ico" type="image/x-icon" />
  <!-- 引用layui文件中layui.css -->
   <link rel="stylesheet" href="../layui/css/layui.css"  media="all"></link>
</head>
<style>
  .login-container{
     width: 320px; margin: 241px auto 0;}
  .reg-other .layui-icon{
     position: relative; display: inline-block; margin: 0 15px; top: 2px; font-size: 30px;}
  body {
     
    background-image: url(../image/login_index.jpg);
    background-size: cover;
    background-repeat: repeat;
  }
  .register-link-container {
     
    text-align: right; /* 右对齐文本 */
  }
  </style>
<body>
<form class="layui-form" id="loginForm">
  <div class="login-container">
    <div class="layui-form-item">
      <div class="layui-input-wrap">
        <div class="layui-input-prefix">
          <i class="layui-icon layui-icon-username"></i>
        </div>
        <input type="number" name="account"  lay-verify="required|phone" placeholder="账户" lay-reqtext="请先填写账户" lay-vertype="tips" autocomplete="off" class="layui-input" lay-affix="clear">
      </div>
    </div>
    <div class="layui-form-item">
      <div class="layui-input-wrap">
        <div class="layui-input-prefix">
          <i class="layui-icon layui-icon-password"></i>
        </div>
        <input type="password" name="password"  lay-verify="required" placeholder="密   码" lay-reqtext="请填写密码" lay-vertype="tips" autocomplete="off" class="layui-input" lay-affix="eye">
      </div>
    </div>
    <div class="layui-form-item">
      <input type="checkbox" name="remember" lay-skin="primary" title="记住密码">
      <a href="/rest" style="float: right; margin-top: 7px;color: #435594;">忘记密码?</a>
    </div>
    <div class="layui-form-item">
      <button class="layui-btn layui-btn-fluid layui-bg-black" lay-submit lay-filter="loginBtn">&nbsp;&nbsp;&nbsp;&nbsp;</button>
    </div>
    <div class="layui-form-item ">
      <a href="/sms" style="position: fixed;color: #435594;">短信快捷登录</a>
      <div class="register-link-container">
       <a href="/register" style="color: #435594;">注册帐号</a> 
      </div>
      <div style="display: flex; align-items: center;">
        <hr class="layui-border-green" style="height: 1px;  flex: 1; margin: 0 5px;">
        <span style="color: gray;font-size: 12px;">其他方式登录</span>
        <hr class="layui-border-green" style="height: 1px;  flex: 1; margin: 0 5px;">
      </div>
      <div class="reg-other">
        <a href="/emailLogin"title="使用QQ邮箱登录" ><i class="layui-icon layui-icon-login-qq" style="color: #1680eb;"></i></a>
        <a href="javascript:;" title="使用微信账号登录" onclick="layer.msg('功能设计开发中')"><i class="layui-icon layui-icon-login-wechat" style="color: #36761e;"></i></a>
        <a href="javascript:;" title="使用微博账号登录" onclick="layer.msg('功能设计开发中')"><i class="layui-icon layui-icon-login-weibo" style="color: #cf1900;"></i></a>
        <a href="javascript:;" title="使用GitHub账号登录" onclick="layer.msg('功能设计开发中')"><i class="layui-icon layui-icon-github" ></i></a>
        <a href="javascript:;" title="使用Windows账户登录" onclick="layer.msg('功能设计开发中')"><i class="layui-icon layui-icon-windows" style="color: #91b0d4;" ></i></a>
      </div>
    </div>
  </div>
</form>
  
<!-- layui.js 地址 -->
<script src="../layui/layui.js"></script> 
<script src="../notify/notify.js"></script>
<script>
  layui.use(['notify'],function(){
     
    var $ = layui.$;
  var form = layui.form;
  var layer = layui.layer;
  var util = layui.util;
  var notify = layui.notify;

    // 方法2: 引用第三方消息通知组件进行表单提交事件
    form.on('submit(loginBtn)', function(data){
     
      var field = data.field; // 获取表单字段值
      if(field.password.length < 6){
     
        notify.info({
     msg:'密码长度不能小于6位',position:'vcenter',shadow:true, closable:false,duration:1000});
        return false;
      }
      /*
      加载提示:用法 notify.info({
                     msg:"提示",//提示信息
                    closable:true,//是否显示关闭按钮 默认是true
                    position:'vcenter',// 指定弹出位置:默认topCenter,可选值:bottomRight|bottomLeft|topRight|topLeft|topCenter|bottomCenter|vcenter"
                    shadow:true,//  是否显示阴影默认是false
                    duration:2000,//显示时间默认3000,为 0 时不自动关闭
                });
      */
      notify.loading({
     msg:'验证登录中,请稍后...',position:'vcenter',shadow:true, closable:false});//显示加载中
      setTimeout(function(){
     
        notify.destroyAll();//关闭所有通知
        $.ajax({
     
          url: '/user/login',
          type: 'post',
          data: {
     account:field.account,
                password:field.password,
                key:1 //1:账户手机号登录;2:短信验证登录;3:邮箱登录
          }, // 数据转换为JSON字符串
          success: function(res) {
     
            if(res.code == 0){
     
              //弹出成功提示
              notify.success({
     msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000});
              //跳转到系统首页,延迟500毫秒
              setTimeout(function(){
     
                location.href = '/main';
              }, 500);
            }else{
     
              //弹出错误提示
              notify.error({
     msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000});
            }
          }
        }).done(function () {
     
          setTimeout(function () {
     
              parent.location.reload();//重载页面
          }, 1500);
        });
      }, 2000);
      // 阻止表单跳转
      return false; //如果不加的话,表单不会跳转但不会进行登录操作
    });


  });
  </script>

 
</body>
</html>
短信验证登录页面(smsLogin.html)

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>暖意书栈快捷账户登录</title>
    <!-- 设置系统图标 -->
    <link rel="shortcut icon" href="../icon/smslogin.ico" type="image/x-icon" />
  <!-- 引用该 layui.css 地址 -->
  <link href="../layui/css/layui.css" rel="stylesheet">
</head>
<style>
  .reg-container{
     width: 320px; margin: 240px auto 0;}
  .reg-other .layui-icon{
     position: relative; display: inline-block; margin: 0 2px; top: 2px; font-size: 26px;}
  body {
     
      background-image: url(../image/login_index.jpg);
      background-size: cover;
      background-repeat: repeat;
    }
    .register-link-container {
     
    text-align: right; /* 右对齐文本 */
  }
  </style>
<body>
<form class="layui-form">
  <div class="reg-container">
    <div class="layui-form-item">
      <div class="layui-input-wrap">
        <div class="layui-input-prefix">
          <i class="layui-icon  layui-icon-cellphone"></i>
        </div>
        <input type="number" name="cellphone" value="" lay-verify="required|phone"  lay-vertype="tips" placeholder="手机号" lay-reqtext="请先填写手机号" autocomplete="off" class="layui-input" id="login-cellphone">
      </div>
    </div>
    <div class="layui-form-item">
      <div class="layui-row">
        <div class="layui-col-xs7">
          <div class="layui-input-wrap">
            <div class="layui-input-prefix">
              <i class="layui-icon layui-icon-vercode"></i>
            </div>
            <input type="text" name="vercode" value="" lay-verify="required" placeholder="验证码"  lay-vertype="tips" lay-reqtext="请填写验证码" autocomplete="off" class="layui-input">
          </div>
        </div>
        <div class="layui-col-xs5">
          <div style="margin-left: 11px;">
            <button type="button" class="layui-btn layui-btn-fluid layui-bg-cyan" lay-on="get-vercode">获取验证码</button>
          </div>
        </div>
      </div>
    </div>
    <div class="layui-form-item">
      <button class="layui-btn layui-btn-fluid layui-bg-cyan" lay-submit lay-filter="loginBtn">&nbsp;&nbsp;&nbsp;&nbsp;</button>
    </div>
    <div class="layui-form-item reg-other">
        <label>其他账号登录</label>
      <span style="padding: 0 21px 0 6px;">
        <a href="/emailLogin"title="使用QQ邮箱登录" "><i class="layui-icon layui-icon-login-qq" style="color: #124e89;"></i></a>
        <a href="javascript:;" title="使用微信账号登录" onclick="layer.msg('功能设计开发中')"><i class="layui-icon layui-icon-login-wechat" style="color: #36761e;"></i></a>
        <ahref="javascript:;" title="使用微博账号登录" οnclick="layer.msg('功能设计开发中')"><i class="layui-icon layui-icon-login-weibo" style="color: #cf1900;"></i></a>
      </span><a href="/" style="color: #435594;">返回账户登录</a>
    </div>
  </div>
</form>
  
<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->
<script src="../layui/layui.js"></script> 
<script src="../notify/notify.js"></script>
<script>
layui.use(function(){
     
  var $ = layui.$;
  var form = layui.form;
  var layer = layui.layer;
  var util = layui.util;
  
 
  
  // 提交事件
  form.on('submit(loginBtn)', function(data){
     
    var field = data.field; // 获取表单字段值
      notify.loading({
     msg:'验证登录中,请稍后...',position:'vcenter',shadow:true, closable:false});//显示加载中
      setTimeout(function(){
     
      notify.destroyAll();
      $.ajax({
     
        url: '/api/verifyCode',
        type: 'POST',
        data: {
     
              phoneNumber:field.cellphone,//手机号
              verificationCode:field.vercode,//验证码
              code:2//1代表注册;2:登录;3:密码重置
        }, // 数据转换为JSON字符串
        success: function(res) {
     
          if(res.success){
     
            //进行账户注册操作
            $.ajax({
     
              url: '/user/login',
              type: 'POST',
              data: {
     
                  account:field.cellphone,
                  key:2 //1:账户登录;2:短信登录;3:邮箱登录
              }, // 数据转换为JSON字符串
              success: function(res) {
     
                if(res.code == 0){
     
                   //弹出成功提示
                  notify.success({
     msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000});
                  //跳转到系统首页,延迟500毫秒
                  setTimeout(function(){
     
                    location.href = '/main';
                  }, 500);
                }else if(res.code == 1){
     
                  notify.warning({
     msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000})
                }else{
     
                  notify.error({
     msg:res.msg,position:'vcenter',shadow:true, closable:false,duration:1000})
                }
              }
            });
          }else{
     
            notify.error({
     msg:res.message,position:'vcenter',shadow:true, closable:false,duration:1000})
          }
        }
      }).done(function () {
     
          setTimeout(function () {
     
              parent.location.reload();//重载页面
          }, 1500);
        });
    },2000)

    return false; // 阻止默认 form 跳转
  });
  
  // 普通事件
  util.on('lay-on', {
     
    // 获取验证码
    'get-vercode': function(othis){
     
      var isvalid = form.validate('#login-cellphone'); // 主动触发验证,v2.7.0 新增 
      //获取输入框的手机号值
      var phoneNumber = $('#login-cellphone').val();
      //验证手机号是否是正确手机号
      if(phoneNumber!=''){
     
        if (!/^1[3456789]\d{9}$/.test(phoneNumber)) {
     
        notify.warning({
     msg:'请输入正确的手机号',position:'vcenter',shadow:true, closable:false,duration:1500});
        return false;
        }
      }
      // 验证通过
      if(isvalid){
     
        $.ajax({
     
          url: '/api/sendCode',
          type: 'POST',
          data: {
      phoneNumber:phoneNumber,//手机号
                  code:2//验证码类型
                },
          success: function(response) {
     
            if (response.success) {
     
              notify.success({
     msg:response.message,position:'vcenter',shadow:true, closable:false,duration:1200});
              // 按钮显示倒计时(60秒后重新获取)
              var countdown = 60; // 直接用秒数进行倒计时
              othis.attr('disabled', true); // 在开始倒计时前禁用按钮
              othis.text(countdown + '秒后重新获取');
              var interval = setInterval(function() {
     
                  if (countdown <= 0) {
      // 当倒计时小于等于0时
                      clearInterval(interval); // 清除倒计时定时器
                      othis.text('获取验证码'); // 恢复按钮文本
                      othis.removeAttr('disabled'); // 恢复按钮的可点击状态
                  } else {
     
                      othis.text(countdown + '秒后重新获取'); // 更新倒计时文本
                      countdown--; // 减少倒计时秒数
                  }
              }, 1000); // 每1000毫秒执行一次,即每秒倒计时递减
            } else {
     
              notify.error({
     msg:response.message,position:'vcenter',shadow:true, closable:false,duration:1000});
            }
          },
          error: function() {
     
            notify.error({
     msg:response.message,position:'vcenter',shadow:true, closable:false,duration:1000});
          }
        });
      }
    }
  });
});
</script>
 
</body>
</html>
邮箱登录页面(emailLogin.html)

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>暖意书栈邮箱登录</title>
  <!-- 设置系统图标 -->
  <link rel="shortcut icon" href="../icon/email.ico" type="image/x-icon" />
  <!-- 引用layui文件中layui.css -->
   <link rel="stylesheet" href="../layui/css/layui.css"  media="all"></link>
</head>
<style>
  .login-container{
     

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

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

相关文章

Profinet 转 EtherCAT 主站网关

一、功能概述 1.1 设备简介 本产品是 PN(Profinet)和 ECAT(EtherCAT)网关&#xff0c;通过数据映射方式工作。 本产品在 PN 侧作为 PN IO 从站&#xff0c;接西门子 PLC 的 Profinet 口&#xff1b;在 ECAT 侧 做为 ECAT 主站&#xff0c;接 ECAT 从站&#xff0c;如伺服驱…

懒人精灵安卓版纯本地离线文字识别插件

目的 懒人精灵是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务&#xff0c;节省大量人工操作的时间。懒人精灵也包含图色功能&#xff0c;识别屏幕上的图像&#xff0c;根据图像的变化自动执行相应的操作。本篇文章主要讲解下更优秀的…

nacos2.x作为配置中心和服务注册和发现以及springcloud使用

目录 一、nacos是什么 二、windows下安装配置nacos 1、准备 2、安装nacos 3、配置nacos 4、启动并且访问nacos 三、springcloud使用nacos作为配置中心 四、springcloud使用nacos进行服务注册与发现 五、springcloud使用nacos进行服务消费 六、nacos的一些高级配置 1…

IP地址申请HTTPS证书

申请IP地址的HTTPS证书是一个相对简单但需要仔细操作的过程。选择合适的CA机构&#xff0c;明确所需证书类型&#xff0c;按照规定步骤提交申请并验证信息&#xff0c;最后正确安装和部署&#xff0c;即可实现通过IP地址访问的安全HTTPS连接。 下面是具体的申请流程&#xff0…

云盘高速视觉检测机,如何提高螺丝件的检测效率?

螺纹螺丝钉是一种常见的螺纹结构紧固件&#xff0c;通常由金属制成&#xff0c;具有螺旋状的螺纹结构。这种螺丝钉旨在通过旋入螺纹孔或材料中&#xff0c;实现可靠的固定连接。 螺纹螺丝钉具有螺旋状的螺纹结构&#xff0c;使其能够轻松旋入金属或其他硬质材料。主要用于金属…

Spring Boot 引入 Guava Retry 实现重试机制

为什么要用重试机制 在如今的系统开发中&#xff0c;为了保证接口调用的稳定性和数据的一致性常常会引入许多第三方的库。就拿缓存和数据库一致性这个问题来说&#xff0c;就有很多的实现方案&#xff0c;如先更新数据库再删除缓存、先更新缓存再更新数据库&#xff0c;又或者…

江苏省发改委副主任钱海云一行莅临我司调研指导

近日&#xff0c;江苏省发改委副主任钱海云、支援合作处副处长卢桐、调研员鲁培和一行&#xff0c;在江宁开发区管委会及市、区发改委有关负责人陪同下&#xff0c;莅临南京天洑软件有限公司走访调研。天洑软件总工程师郭阳博士携管理层参与本次调研活动。 在参观过程中&#x…

【C++】选择结构- 嵌套if语句

嵌套if语句的语法格式&#xff1a; if(条件1) { if(条件1满足后判断是否满足此条件) {条件2满足后执行的操作} else {条件2不满足执行的操作} } 下面是一个实例 #include<iostream> using namespace std;int main4() {/*提示用户输入一个高考分数&#xff0c;根据分…

通过 Function-Call Input Events启用图表中的控制状态

在由function-call input event启用的图表中&#xff0c;可以通过设置启用图表时的状态属性来控制状态的行为。根据此属性的值&#xff0c;当输入事件重新启用图表时&#xff0c;状态要么保持其最新值&#xff0c;要么恢复为初始值。要修改属性&#xff0c;请执行以下操作&…

一文读懂《制造业数字化转型行动方案》

​在推动新型工业化与构建现代化产业体系的宏伟蓝图中&#xff0c;制造业的数字化转型无疑是至关重要的一环。随着国务院常务会议正式批准《制造业数字化转型行动方案》&#xff08;简称《方案》&#xff09;&#xff0c;标志着我国制造业正式迈入了一个全面拥抱数字化、智能化…

C++迈向精通:STL-iterator_traits迭代器类型萃取解析

STL-iterator_traits迭代器类型萃取解析 源码 在阅读STL源码的时候遇到了这样的一行代码&#xff1a; 通过ctags跳转到对应的定义区域&#xff1a; 下面还有两个特化版本&#xff1a; 根据英文释义&#xff0c;发现模板中需要传入的是一个迭代器类型&#xff0c;在上面找到源…

NAND Flash 的 SDR、ONFI、DDR 接口

NAND Flash 的 SDR、ONFI、DDR 接口 1. 省流导图 2. SDR、ONFI、DDR 概述 2.1 SDR (Single Data Rate) SDR&#xff08;Single Data Rate&#xff09;是指读写数据使用 单个时钟信号的边缘&#xff0c;即上升沿或下降沿 。在 SDR 模式下&#xff0c;数据的传输速率受限于时钟…

用友U8 Cloud MeasureQueryFrameAction接口处SQL注入漏洞复现 [附POC]

文章目录 用友U8 Cloud MeasureQueryFrameAction接口处SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现用友U8 Cloud MeasureQueryFrameAction接口处SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿…

【Gin】深度解析:在Gin框架中优化应用程序流程的责任链设计模式(上)

【Gin】深度解析&#xff1a;在Gin框架中优化应用程序流程的责任链设计模式(上) 大家好 我是寸铁&#x1f44a; 【Gin】深度解析&#xff1a;在Gin框架中优化应用程序流程的责任链设计模式(上)✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 本次文章分为上下两部分&#xf…

Jenkins的相关概述和安装

Jenkins 1.什么是jenkins Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。耗内存max 2. 为什么使用Jenkins 拉取、编译、打包…

AI绘画入门实践|Midjourney:使用 --no 去除不想要的物体

在 Midjourney 中&#xff0c;--no 作为反向提示词&#xff0c;告诉 MJ 在生成图像时&#xff0c;不要包含什么。 使用格式&#xff1a;--no 对应物体提示词&#xff08;多个物体之间使用","间隔&#xff09; 使用演示 a web banner, summer holiday --v 6.0 a web b…

变阻器在实际应用中需要注意哪些安全事项?

变阻器是广泛应用于电子设备中的电子元件&#xff0c;它可以改变电阻值以控制电流的大小。然而&#xff0c;在实际应用中&#xff0c;如果操作不当&#xff0c;可能会引发一些安全问题。因此&#xff0c;使用变阻器时&#xff0c;必须注意以下安全事项&#xff1a; 1. 选择合适…

windows wsl ubuntu系统安装桌面可视化

参考&#xff1a; https://www.bilibili.com/read/cv33557374/ 1&#xff09;首先先安装好wsl ubuntu系统 2&#xff09;安装 Ubuntu 桌面版 sudo apt purge -y acpid acpi-support modemmanagersudo apt-mark hold acpid acpi-support modemmanager sudo apt install ubunt…

UE4如何直接调试Game

某些功能在编辑器里不好调试&#xff0c;例如Pak&#xff0c;就需要直接调试 Game&#xff0c;做法是选择 Game&#xff0c;不要选择Client&#xff0c;加断点&#xff0c;然后点击 Debug 就好了。 断点调试成功&#xff1a; 同时看到界面&#xff1a;

中国森林地上和地下生物量碳变化数据集(2002-2021年)

中国森林地上和地下生物量碳变化数据集&#xff08;2002-2021年&#xff09; 数据介绍 为了量化中国近期全国性恢复工作的生态后果&#xff0c;过去20年森林生物量碳储量变化的空间显性信息至关重要。然而&#xff0c;在全国范围内进行长期生物量追踪仍然具有挑战性&#xff0c…