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 相关文章推荐
JavaScript触发器详解
Mar 10 Javascript
下载网站打开页面后间隔多少时间才显示下载链接地址的代码
Apr 25 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
Oct 11 Javascript
JavaScript中prototype为对象添加属性的误区介绍
Oct 15 Javascript
JS注释所产生的bug 即使注释也会执行
Nov 19 Javascript
JavaScript中的lastIndexOf()方法使用详解
Jun 06 Javascript
JS控件bootstrap datepicker使用方法详解
Mar 25 Javascript
基于Bootstrap框架菜鸟入门教程(推荐)
Sep 17 Javascript
vue 登录滑动验证实现代码
Aug 24 Javascript
Vue表单及表单绑定方法
Sep 04 Javascript
es6函数之严格模式用法实例分析
Mar 17 Javascript
js实现电灯开关效果
Jan 19 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函数(简单整理)
2010/04/30 PHP
PHP utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码
2013/04/08 PHP
基于MySQL分区性能的详细介绍
2013/05/02 PHP
深入php list()函数的详解
2013/06/05 PHP
Yii入门教程之目录结构、入口文件及路由设置
2014/11/25 PHP
PHP区块查询实现方法分析
2018/05/12 PHP
CI(CodeIgniter)框架中URL特殊字符处理与SQL注入隐患分析
2019/02/28 PHP
php进行md5加密简单实例方法
2019/09/19 PHP
PHP xpath提取网页数据内容代码解析
2020/07/16 PHP
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
Javascript string 扩展库代码
2010/04/09 Javascript
DOM_window对象属性之--clipboardData对象操作代码
2011/02/03 Javascript
鼠标滑在标题上显示图片的JS代码
2013/11/19 Javascript
javascript匿名函数应用示例介绍
2014/03/07 Javascript
jQuery源码解读之hasClass()方法分析
2015/02/20 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
理解JavaScript表单的基础知识
2016/01/25 Javascript
深入浅析JavaScript中数据共享和数据传递
2016/04/25 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
vue实现带过渡效果的下拉菜单功能
2020/02/19 Javascript
vue-router重写push方法,解决相同路径跳转报错问题
2020/08/07 Javascript
使用Python实现一个简单的项目监控
2015/03/31 Python
python实现决策树ID3算法的示例代码
2018/05/30 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
Python实现针对json中某个关键字段进行排序操作示例
2018/12/25 Python
python实现文本进度条 程序进度条 加载进度条 单行刷新功能
2019/07/03 Python
python使用原始套接字发送二层包(链路层帧)的方法
2019/07/22 Python
TensorFlow加载模型时出错的解决方式
2020/02/06 Python
Python类super()及私有属性原理解析
2020/06/15 Python
实例讲解使用SVG制作loading加载动画的方法
2016/04/05 HTML / CSS
斯凯奇美国官网:SKECHERS美国
2016/08/20 全球购物
应届硕士毕业生自荐信
2014/05/26 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
2014年语文教研组工作总结
2014/12/06 职场文书
党员个人总结自评
2015/02/14 职场文书
父亲节寄语大全
2015/02/27 职场文书