登录页面大改,加入邮箱验证系统

master
LCJ-MinYa 7 years ago
parent f0b1578cd0
commit 80ae501705
  1. 11
      config/config.js
  2. 1
      model/user.server.module.js
  3. 5
      package-lock.json
  4. 1
      package.json
  5. 40
      routes/api/forget.js
  6. 15
      routes/api/login.js
  7. 23
      routes/api/register.js
  8. 42
      routes/api/reset.js
  9. 6
      routes/router.js
  10. 45
      routes/utils/mail.js
  11. 2
      views/common/header.html
  12. 68
      views/login.html
  13. 9
      www/css/login.css
  14. 133
      www/js/login.js
  15. 10
      www/utils/utils.js

@ -4,5 +4,14 @@
*/
module.exports = {
mongodb: "mongodb://chatRoot:123456@106.15.193.97:9000/chat",
port: 8083
port: 8083,
MAIL: {
service: '163',
secureConnection: true,
port: 465,
auth: {
user: 'xlzzslzy@163.com',
pass: 'lcj136409'
}
},
}

@ -5,6 +5,7 @@ var db = require('../config/mongoose.js');
//申明一个mongoons对象
var UserSchema = new mongoose.Schema({
userName: String,
email: String,
password: String,
uid: String,
time: {

5
package-lock.json generated

@ -600,6 +600,11 @@
"resolved": "http://registry.npm.taobao.org/negotiator/download/negotiator-0.6.1.tgz",
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
},
"nodemailer": {
"version": "4.3.1",
"resolved": "http://registry.npm.taobao.org/nodemailer/download/nodemailer-4.3.1.tgz",
"integrity": "sha1-QOFi9UGTui/syiANVE6PbBEG1pQ="
},
"object-assign": {
"version": "4.1.0",
"resolved": "http://registry.npm.taobao.org/object-assign/download/object-assign-4.1.0.tgz",

@ -14,6 +14,7 @@
"moment": "^2.17.1",
"mongoose": "^4.7.1",
"morgan": "~1.7.0",
"nodemailer": "^4.3.1",
"serve-favicon": "~2.3.0",
"socket.io": "^1.7.2"
}

@ -0,0 +1,40 @@
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var utils = require('../utils/utils.js');
var mail = require('../utils/mail.js');
require('../../model/user.server.module.js');
var User = mongoose.model('User');
/* GET home page. */
router.get('/forget', function(req, res) {
res.send("请求资源不支持HTTP方法GET访问!");
});
router.post('/forget', function(req, res) {
User.findOne({
email: req.body.email
}, function(err, result) {
if (err) {
utils.sendJson(res, 404, err);
} else {
if (result) {
var subject = '恣意游用户重置密码';
var url = req.protocol + "://" + req.get('host') + '/login?uid=' + result.uid;
var html = '<p>亲爱的用户:</p><br/><p>感谢您使用恣意游重置密码功能.</p><p>请点击以下链接完成重置功能</p>';
html += '<p><a href="' + url + '">' + url + '</a></p>';
mail.sendMail(req.body.email, subject, html, function(result) {
if (result.status == 200) {
utils.sendJson(res, 200, result.message);
} else {
utils.sendJson(res, 404, result.message);
}
})
} else {
utils.sendJson(res, 404, '该邮箱地址暂未注册');
}
}
})
});
module.exports = router;

@ -12,17 +12,20 @@ router.get('/login', function(req, res) {
router.post('/login', function(req, res) {
User.findOne({
userName: req.body.userName
email: req.body.email
}, function(err, result) {
if (err) {
utils.sendJson(res, 404, err);
} else {
if (result) {
if (result.password == req.body.password) utils.sendJson(res, 200, '登录成功', {
uid: result.uid,
userName: result.userName
});
else utils.sendJson(res, 404, '密码错误');
if (result.password == req.body.password && result.password) {
utils.sendJson(res, 200, '登录成功', {
uid: result.uid,
userName: result.userName
});
} else {
utils.sendJson(res, 404, '密码错误');
}
} else {
utils.sendJson(res, 404, '用户不存在');
}

@ -2,6 +2,7 @@ var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var utils = require('../utils/utils.js');
var mail = require('../utils/mail.js');
require('../../model/user.server.module.js');
var User = mongoose.model('User');
@ -12,13 +13,13 @@ router.get('/register', function(req, res) {
router.post('/register', function(req, res) {
User.findOne({
userName: req.body.userName
email: req.body.email
}, function(err, result) {
if (err) {
utils.sendJson(res, 404, err);
} else {
if (result) {
utils.sendJson(res, 404, '用户名已注册');
utils.sendJson(res, 404, '该邮箱地址已注册');
} else {
userInsert();
}
@ -28,7 +29,8 @@ router.post('/register', function(req, res) {
var userInsert = function() {
var content = {
userName: req.body.userName,
password: req.body.password,
email: req.body.email,
password: '',
uid: utils.generateUUID()
}
var user = new User(content);
@ -36,10 +38,17 @@ router.post('/register', function(req, res) {
if (err) {
utils.sendJson(res, 404, err);
} else {
utils.sendJson(res, 200, "注册成功", {
uid: content.uid,
userName: content.userName
});
var subject = '恣意游用户验证';
var url = req.protocol + "://" + req.get('host') + '/login?uid=' + content.uid;
var html = '<p>亲爱的用户:</p><br/><p>感谢您注册恣意游.</p><p>请点击以下链接完成注册</p>';
html += '<p><a href="' + url + '">' + url + '</a></p>';
mail.sendMail(req.body.email, subject, html, function(result) {
if (result.status == 200) {
utils.sendJson(res, 200, result.message);
} else {
utils.sendJson(res, 404, result.message);
}
})
}
})
}

@ -0,0 +1,42 @@
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var utils = require('../utils/utils.js');
require('../../model/user.server.module.js');
var User = mongoose.model('User');
/* GET home page. */
router.get('/reset', function(req, res) {
res.send("请求资源不支持HTTP方法GET访问!");
});
router.post('/reset', function(req, res) {
User.update({
uid: req.body.uid
}, {
$set: {
password: req.body.password
}
}, {}, function(err, result) {
if (err) {
utils.sendJson(res, 404, err);
} else {
var resultObj = JSON.parse(JSON.stringify(result));
console.log(resultObj);
if (resultObj.nModified == 0) {
utils.sendJson(res, 404, '用户不存在');
} else {
User.findOne({
uid: req.body.uid
}, function(err, result) {
utils.sendJson(res, 200, '密码修改成功', {
uid: result.uid,
userName: result.userName
});
});
}
}
});
});
module.exports = router;

@ -26,6 +26,10 @@ module.exports = function(app, express, path) {
app.use('/api', loginApi);
var registerApi = require('./api/register');
app.use('/api', registerApi);
var resetApi = require('./api/reset.js');
app.use('/api', resetApi);
var forgetApi = require('./api/forget.js');
app.use('/api', forgetApi);
var creatRoomApi = require('./api/creatRoom.js');
app.use('/api', creatRoomApi);
var getRoomList = require('./api/getRoomList.js');
@ -33,7 +37,7 @@ module.exports = function(app, express, path) {
app.use(express.static(path.join(__dirname, '../www'), {
maxAge: 1000 * 60 * 60
maxAge: 0
}));
//404和错误程序处理

@ -0,0 +1,45 @@
'use strict';
/*--发送邮件--*/
var Nodemailer = require('nodemailer');
/*--基本配置--*/
var Config = require('../../config/config.js');
var smtpTransport = Nodemailer.createTransport(Config.MAIL);
/**
* [sendMail 发送邮件]
* @param {String} subject发送的主题
* @param {String} html发送的 html 内容
*/
var sendMail = function(emailAddress, subject, html, callback) {
var emailAddressArr = [];
emailAddressArr.push(emailAddress);
var mailOptions = {
from: '希希里岸 <xlzzslzy@163.com>',
to: emailAddressArr,
subject: subject,
html: html
};
smtpTransport.sendMail(mailOptions, function(error, response) {
if (error) {
callback({
status: 404,
message: '邮件发送失败',
data: error
});
} else {
callback({
status: 200,
message: '邮件发送成功',
data: response
});
}
smtpTransport.close();
});
};
module.exports = {
sendMail
}

@ -7,7 +7,7 @@
<meta name="format-detection" content="telephone=no, email=no"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_iol3eq6qsfoxyldi.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_207590_whm0gmw0m37hkt9.css">
<link rel="stylesheet" href="/css/<%= pageName%>.css">
</head>
<body>

@ -13,14 +13,14 @@
<transition name="loginShow">
<div class="login-input-box" v-show="!firstLoading && login">
<div class="login-username">
<i class="iconfont icon-username"></i>
<input type="text" class="login-input" maxlength="15" v-model="userName" placeholder="请输入您的账号">
<i class="iconfont icon-1"></i>
<input type="text" class="login-input" maxlength="30" v-model="email" placeholder="请输入您的邮箱地址">
</div>
<div class="login-username login-password">
<i class="iconfont icon-password"></i>
<input type="password" class="login-input" v-model="password" maxlength="15" placeholder="请输入您的密码">
</div>
<button type="button" class="login-btn" @click="userLogin" v-bind="{disabled:reqLoading}">
<button type="button" class="login-btn" @click="checkOutMsg('login')" v-bind="{disabled:reqLoading}">
<div class="login-btn-box" :class="{'btn-width':reqLoading}">
<i class="css-loading" v-if="reqLoading"></i>
<i class="login-btn-text">登录</i>
@ -29,29 +29,71 @@
</div>
</transition>
<!--register-->
<transition name="registerShow">
<div class="register-input-box" v-show="!firstLoading && register">
<div class="login-input-box" v-show="!firstLoading && register">
<div class="login-username">
<i class="iconfont icon-1"></i>
<input type="text" class="login-input" maxlength="30" v-model="email" placeholder="请输入您的邮箱地址">
</div>
<div class="login-username login-password">
<i class="iconfont icon-username"></i>
<input type="text" class="login-input" maxlength="15" v-model="userName" placeholder="请输入您的账号">
<input type="text" class="login-input" maxlength="30" v-model="userName" placeholder="请输入您的昵称">
</div>
<button type="button" class="login-btn" @click="checkOutMsg('register')" v-bind="{disabled:reqLoading}">
<div class="login-btn-box" :class="{'btn-width':reqLoading}">
<i class="css-loading" v-if="reqLoading"></i>
<i class="login-btn-text">验证</i>
</div>
</button>
</div>
</transition>
<!--forget-->
<transition name="registerShow">
<div class="login-input-box" v-show="!firstLoading && forget">
<div class="login-username">
<i class="iconfont icon-1"></i>
<input type="text" class="login-input" maxlength="30" v-model="email" placeholder="请输入您的邮箱地址">
</div>
<div class="login-username register-password">
<div class="login-username login-password">
<i class="iconfont icon-password"></i>
<input type="password" class="login-input" maxlength="15" v-model="password" placeholder="请输入您的密码">
<input type="password" class="login-input" v-model="password" maxlength="15" placeholder="请输入验证码">
</div>
<div class="login-username register-password">
<button type="button" class="login-btn" @click="checkOutMsg('forget')" v-bind="{disabled:reqLoading}">
<div class="login-btn-box" :class="{'btn-width':reqLoading}">
<i class="css-loading" v-if="reqLoading"></i>
<i class="login-btn-text">验证</i>
</div>
</button>
</div>
</transition>
<!--reset-->
<transition name="registerShow">
<div class="login-input-box" v-show="!firstLoading && reset">
<div class="login-username">
<i class="iconfont icon-password"></i>
<input type="password" class="login-input" maxlength="15" v-model="confirmPassword" placeholder="请确认您的密码">
<input type="password" class="login-input" v-model="password" maxlength="15" placeholder="请输入您的密码">
</div>
<input type="submit" class="login-btn register-btn" value="点击注册" @click="userRegister">
<div class="login-username login-password">
<i class="iconfont icon-password"></i>
<input type="password" class="login-input" v-model="confirmPassword" maxlength="15" placeholder="请确认您的密码">
</div>
<button type="button" class="login-btn" @click="checkOutMsg('password')" v-bind="{disabled:reqLoading}">
<div class="login-btn-box" :class="{'btn-width':reqLoading}">
<i class="css-loading" v-if="reqLoading"></i>
<i class="login-btn-text">重置</i>
</div>
</button>
</div>
</transition>
<!--foot-->
<div class="login-foot-box">
<span>忘记密码</span>
<span @click="toggleShow" v-show="login">点击注册</span>
<span @click="toggleShow" v-show="register">返回登录</span>
<span @click="toggleShow('forget')" v-show="login">忘记密码</span>
<span @click="toggleShow('register')" v-show="login">点击注册</span>
<span @click="toggleShow" v-show="register || forget || reset">已有账号,直接登录</span>
</div>
</div>
</transition>

@ -41,14 +41,7 @@ html,body{
font-size: 1.6rem;
}
.register-input-box{
position: absolute;
top:35%;
left: 50%;
width: 80%;
overflow: hidden;
margin-left: -40%;
color: #f1f1f1;
font-size: 1.6rem;
}
.login-username{
position: relative;
@ -70,7 +63,7 @@ html,body{
background: rgba(0,0,0,0);
color:#fff;
}
.icon-username,.icon-password{
.icon-username, .icon-password, .icon-1{
color: #eacb20;
font-size: 1rem;
text-align: center;

@ -13,11 +13,14 @@
data: function() {
return {
firstLoading: true,
login: true,
login: false,
register: false,
forget: false,
reqLoading: false,
reset: false,
userName: "",
password: "",
email: '',
confirmPassword: "",
popup: {
showPopupText: false,
@ -33,52 +36,94 @@
var _this = this;
this.$nextTick(function() {
_this.firstLoading = false;
console.log(GZL.GetQueryString('uid'));
if (GZL.GetQueryString('uid')) {
_this.reset = true;
} else {
_this.login = true;
}
})
},
methods: {
toggleShow: function() {
toggleShow: function(name) {
this.login = !this.login;
this.register = !this.register;
if (name == 'register' || this.register) {
this.register = !this.register;
}
if (name == 'forget' || this.forget) {
this.forget = !this.forget;
}
if (this.reset) {
this.reset = false;
}
},
userLogin: function() {
checkOutMsg: function(type) {
var _this = this;
if (this.userName && this.password) {
GZL.ajax({
url: GZL.CONFIG.LOGIN,
method: "POST",
data: {
userName: this.userName,
password: this.password
},
success: function(result) {
if (result.status === 200) {
GZL.setCookie("uid", result.data.uid, {
expires: 24 * 7
})
GZL.setCookie("userName", result.data.userName, {
expires: 24 * 7
})
window.location.href = 'index';
} else GZL.popue(_this, result.message);
if (type == 'register' || type == 'login') {
if (!this.email) {
GZL.popue(_this, "邮箱地址不能为空");
return;
}
if (!GZL.MatchEmail(this.email)) {
GZL.popue(_this, "请输入正确的邮箱地址");
return;
}
}
if (type == 'register') {
if (!this.userName) {
GZL.popue(_this, "昵称不能为空");
return;
}
if (this.userName.length < 2) {
GZL.popue(_this, "昵称不能小于两个字符");
return;
}
}
if (type == 'password' || type == 'login') {
if (!this.password) {
GZL.popue(_this, "密码不能为空");
return;
}
if (this.password.length < 6) {
GZL.popue(_this, "密码不能小于6位数");
return;
}
if (type == 'password') {
if (this.confirmPassword != this.password) {
GZL.popue(_this, "两次密码不相等");
return;
}
}, _this);
} else {
if (!this.userName) GZL.popue(_this, "账号不能为空");
else if (!this.password) GZL.popue(_this, "密码不能为空");
}
}
this.userBtnClick(type);
},
userRegister: function() {
userBtnClick: function(type) {
var _this = this;
if (this.userName && this.password && this.confirmPassword && this.password == this.confirmPassword) {
GZL.ajax({
url: GZL.CONFIG.REGISTER,
method: "POST",
data: {
userName: this.userName,
password: this.password
},
success: function(result) {
if (result.status === 200) {
var url = '';
if (type == 'login') {
url = GZL.CONFIG.LOGIN;
} else if (type == 'register') {
url = GZL.CONFIG.REGISTER;
} else if (type == 'password') {
url = GZL.CONFIG.RESET;
} else if (type == 'forget') {
url = GZL.CONFIG.FORGET;
}
GZL.ajax({
url: url,
method: "POST",
data: {
email: this.email,
userName: this.userName,
password: this.password,
uid: GZL.GetQueryString('uid')
},
success: function(result) {
if (result.status === 200) {
if (type == 'login' || type == 'password') {
GZL.setCookie("uid", result.data.uid, {
expires: 24 * 7
})
@ -86,14 +131,14 @@
expires: 24 * 7
})
window.location.href = 'index';
} else GZL.popue(_this, result.message);
} else {
GZL.popue(_this, result.message);
}
} else {
GZL.popue(_this, result.message);
}
}, _this);
} else {
if (!this.userName) GZL.popue(_this, "账号不能为空");
else if (!this.password || !this.confirmPassword) GZL.popue(_this, "密码不能为空");
else if (this.password != this.confirmPassword) GZL.popue(_this, "两次密码不相等");
}
}
}, _this);
}
}
});

@ -22,7 +22,9 @@ var GZL = (function(root, factory) {
LOGIN: "/api/login",
REGISTER: "/api/register",
CREATROOM: "/api/creatRoom",
ROOMLIST: "/api/getRoomList"
ROOMLIST: "/api/getRoomList",
RESET: "/api/reset",
FORGET: "/api/forget",
};
factory.popue = function(_this, text) {
@ -42,6 +44,12 @@ var GZL = (function(root, factory) {
return null;
};
//邮箱地址正则表达式判断
factory.MatchEmail = function(string) {
var reg = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
return reg.test(string);
}
/**
* [ajax 封装ajax]
* @param {[object]} options

Loading…
Cancel
Save