Node+Express+MongoDB实现登录注册功能实例


Posted in Javascript onApril 23, 2017

注入MongoDB 依赖

var mongoose = require("mongoose");

由于需要进行表单处理,需要用到bodyParser中间件

bodyParser模块来做文件解析,将表单里的数据进行格式化

var bodyParser = require("body-parser"); 
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

登录后将用户信息保存下来,需要使用session中间件,它依赖cookieParser中间件

var cookieParser = require('cookie-parser');
var session = require('express-session');
ar mongoStore = require('connect-mongo')(session);
var dbUrl = 'mongodb://localhost/express';
app.use(cookieParser()); 
app.use(session({
 secret:'express',
 store: new mongoStore({
 url: dbUrl,
 collection: 'sessions'
 })
}));

使用jade模板

layout.jade

doctype html
html
 head
  meta(charset='utf-8')
  title #{title}
  include ./includes/head
 body
  include ./includes/header
  block content

head.jade

link(href='css/main.css', rel='stylesheet')
link(href="/libs/bootstrap/dist/css/bootstrap.min.css" rel="external nofollow" , rel="stylesheet")
script(src="/libs/jquery/dist/jquery.min.js")
script(src="/libs/bootstrap/dist/js/bootstrap.min.js")

header.jade

.container
 .row
  .page-header
   h1 #{title}
.navbar.navbar-default.navbar-fixed-bottom
 .container
  if user
   p.navbar-text.navbar-right
    span 欢迎你,#{user.name}
    span  | 
    a.navbar-link(href="/layout" rel="external nofollow" ) 退出登录
  else
   p.navbar-text.navbar-right
    a.navbar-link(href="/signup" rel="external nofollow" , data-toggle="modal", data-target="#signupModal") 注册
    span  | 
    a.navbar-link(href="/login" rel="external nofollow" , data-toggle="modal", data-target="#signinModal") 登录

signup.jade

include ../layout
 block content
  form.form-horizontal( role="form", method="POST", action='/user/signup')
   .form-group
    label.col-sm-2.control-label(for="signupName") 用户名
    .col-sm-10
     input#signupName.form-control(type="text", name="user[name]", placeholder="输入用户名")
   .form-group
    label.col-sm-2.control-label(for="signuppassword") 密码
    .col-sm-10
     input#signuppassword.form-control(type="password", name="user[password]", placeholder="输入密码")
   .form-group
    label.col-sm-2.control-label(for="signupemail") 邮箱
    .col-sm-10
     input#signupemail.form-control(type="email", name="user[email]", placeholder="输入邮箱")
   .form-group
    .col-sm-offset-2.col-sm-10
     button.btn.btn-default(type="submit") 完成注册

配置路由

登录注册页面

// 注册页面
app.get('/signup', function (req,res) {
 res.render('signup', {
 title: '注册'
 });
});
// 登录页面
app.get('/login', function (req,res) {
 res.render('login', {
 title: '登录'
 });
});

注册功能

// 注册表单
app.post('/user/signup', function (req,res) {
 var _user = req.body.user;
 User.findOne({name:_user.name}, function (err, user) {
 if(err){
  console.log(err);
 }
 if(user) {
  return res.redirect('/login');
 } else {
  var user = new User(_user);
  user.save(function (err, user) {
  if(err){
   console.log(err);
   res.redirect('/signup');
  }
  console.log('注册成功——用户名:' + user);
  res.redirect('/login'); 
  });
 }
 });
});

登录功能

// 登录表单
app.post('/user/login', function (req,res) {
 var _user = req.body.user;
 var name = _user.name;
 var password = _user.password;
 User.findOne({name:name}, function (err, user) {
 if(err){
  console.log(err);
 }
 if(!user) {
  return res.redirect('/signup');
 }
 user.comparePassword(password, function (err, isMatch) {
  if (err){
  console.log(err);
  }
  if (isMatch) {
  req.session.user = user; // 用户名存入session中
  console.log('登录成功——用户名: ' + user);
  return res.redirect('/');
  } else {
  return res.redirect('/lgoin');
  }
 });
 });
});

退出登录

app.get('/layout', function(req,res){
 delete req.session.user;
 //delete app.locals.user; // 删除全局变量user,否则点击退出登录,页面无变化
 res.redirect('/');
});

登录注册的数据库操作

连接数据库

mongoose.connect("mongodb://localhost/express"); // 连接数据库

schema模式定义

数据的更新和查找,以及密码加盐

//schemas/user.js
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var SALT_WORK_FSCTOR = 10; // 计算强度,越大破解越困难
var UserSchema = new mongoose.Schema({
 name: {
 unique: true,
 type:String
 },
 password: String,
 email:String,
 meta: {
 createAt: {
  type: Date,
  default: Date.now()
 },
 updateAt: {
  type: Date,
  default: Date.now()
 }
 }
});
//每次存入数据时都进行判断
UserSchema.pre('save', function (next) {
 var user = this;
 if (this.isNew) { // 数据是新数据
 this.meta.createAt = this.meta.updateAt = Date.now();
 } else {
 this.meta.updateAt = Date.now();
 }
 //密码 加盐
 bcrypt.genSalt(SALT_WORK_FSCTOR, function (err, salt) {
 if (err) {
  return next(err);
 }
 bcrypt.hash(user.password, salt, function (err, hash) {
  if (err) {
  return next(err);
  }
  user.password = hash;
  next();
 });
 });
});
UserSchema.methods = {
 comparePassword: function (_password, cb) {
 bcrypt.compare(_password, this.password, function (err, isMatch) {
  if (err) {
  return cb(err);
  }
  cb(null, isMatch);
 })
 }
};
UserSchema.statics = {
 fetch: function (cb) {
 return this
  .find({})
  .sort('meta.updateAt')
  .exec(cb);
 },
 findById: function (id, cb) {
 return this
  .findOne({_id: id})
  .exec(cb)
 }
};
module.exports = UserSchema;

model编译模型

// models/user.js
var mongoose = require('mongoose');
//模式
var UserSchema = require('../schemas/user');
//编译模型
var User = mongoose.model('user',UserSchema);
module.exports = User;

入口文件注入

//app.js
var User = require('./models/user');
app.set('view engine', 'jade'); // jade模板引擎
app.set("views", "./views/pages/"); // 视图根目录
var serveStatic = require('serve-static'); // 静态文件处理
app.use(serveStatic('public')); // 路径:public

身份验证中间件

获取session的用户名,存入到locals中,暴露给视图使用,即header.jade中可以获取到user。

app.use(function (req, res, next) {
 var _user = req.session.user;
 app.locals.user = _user;
 return next();
});

以上所述是小编给大家介绍的Node+Express+MongoDB实现登录注册功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery对象和DOM对象的区别介绍
Aug 09 Javascript
JS实现可拖曳、可关闭的弹窗效果
Sep 26 Javascript
JS获取鼠标选中的文字
Aug 10 Javascript
微信小程序 网络API发起请求详解
Nov 09 Javascript
jquery-mobile表单的创建方法详解
Nov 23 Javascript
codeMirror插件使用讲解
Jan 16 Javascript
原生js轮播(仿慕课网)
Feb 15 Javascript
vue使用Element组件时v-for循环里的表单项验证方法
Jun 28 Javascript
JavaScript中创建原子的方法总结
Aug 26 Javascript
javascript实现考勤日历功能
Nov 29 Javascript
原生js实现移动端Touch轮播图的方法步骤
Jan 03 Javascript
ES11屡试不爽的新特性,你用上了几个
Oct 21 Javascript
使用jQuery ajaxupload插件实现无刷新上传文件
Apr 23 #jQuery
基于JavaScript实现类名的添加与移除
Apr 23 #Javascript
源码分析Vue.js的监听实现教程
Apr 23 #Javascript
Bootstrap进度条与AJAX后端数据传递结合使用实例详解
Apr 23 #Javascript
springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项
Apr 23 #Javascript
Node.js中的require.resolve方法使用简介
Apr 23 #Javascript
AngularJS之ionic 框架下实现 Localstorage本地存储
Apr 22 #Javascript
You might like
PHP通过header实现文本文件下载的代码
2010/08/08 PHP
PHP学习笔记(二) 了解PHP的基本语法以及目录结构
2014/08/04 PHP
jQuery Tools Dateinput使用介绍
2012/07/14 Javascript
基于SVG的web页面图形绘制API介绍及编程演示
2013/06/28 Javascript
千分位数字格式化(用逗号隔开 代码已做了修改 支持0-9位逗号隔开)的JS代码
2013/12/05 Javascript
node.js中的http.response.removeHeader方法使用说明
2014/12/14 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
KnockoutJS 3.X API 第四章之click绑定
2016/10/10 Javascript
vue webpack打包后图片路径错误的完美解决方法
2018/12/07 Javascript
vue滚动固定顶部及修改样式的实例代码
2019/05/30 Javascript
tornado框架blog模块分析与使用
2013/11/21 Python
Python时间模块datetime、time、calendar的使用方法
2016/01/13 Python
python pandas库的安装和创建
2019/01/10 Python
Python应用领域和就业形势分析总结
2019/05/14 Python
Python3实现二叉树的最大深度
2019/09/30 Python
python使用hdfs3模块对hdfs进行操作详解
2020/06/06 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
修复iPhone的safari浏览器上submit按钮圆角bug
2012/12/24 HTML / CSS
澳大利亚第一的设计师礼服租赁网站:GlamCorner
2017/08/13 全球购物
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
介绍一下linux文件系统分配策略
2013/02/25 面试题
北京捷通华声语音技术有限公司Java软件工程师笔试题
2012/04/10 面试题
机械制造与自动化应届生求职信
2013/11/16 职场文书
小区门卫值班制度
2014/01/24 职场文书
学生思想表现的评语
2014/01/30 职场文书
教师暑期培训感言
2014/08/15 职场文书
安全保卫工作竞聘材料
2014/08/25 职场文书
乡领导班子四风问题对照检查材料
2014/09/25 职场文书
劳动争议仲裁代理词
2015/05/25 职场文书
Python包argparse模块常用方法
2021/06/04 Python
Tomcat用户管理的优化配置详解
2022/03/31 Servers
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python
Nginx本地配置SSL访问的实例教程
2022/05/30 Servers