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">登 录</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">登 录</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{