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 相关文章推荐
csdn 博客的css样式 v3
Feb 24 Javascript
jQuery 处理表单元素的代码
Feb 15 Javascript
Jquery同辈元素选中/未选中效果的实例代码
Aug 01 Javascript
鼠标经过显示二级菜单js特效
Aug 13 Javascript
jquery.ui.draggable中文文档(原文翻译)
Nov 15 Javascript
JavaScript中创建对象和继承示例解读
Feb 12 Javascript
Backbone.js 0.9.2 源码注释中文翻译版
Jun 25 Javascript
在localStorage中存储对象数组并读取的方法
Sep 24 Javascript
AngularJS 霸道的过滤器小结
Apr 26 Javascript
详解AngularJs路由之Ui-router-resolve(预加载)
Jun 13 Javascript
JS与CSS3实现图片响应鼠标移动放大效果示例
May 04 Javascript
详解iview的checkbox多选框全选时校验问题
Jun 10 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
《猛禽小队》:DC宇宙的又一超级大烂片
2020/04/09 欧美动漫
PHP自带函数给数字或字符串自动补齐位数
2014/07/29 PHP
php json_encode()函数返回json数据实例代码
2014/10/10 PHP
PHP实现设计模式中的抽象工厂模式详解
2014/10/11 PHP
Yii2实现UploadedFile上传文件示例
2017/02/15 PHP
用js+xml自动生成表格的东西
2006/12/21 Javascript
javascript下查找父节点的简单方法
2007/08/13 Javascript
jQuery实现的图片分组切换焦点图插件
2015/01/06 Javascript
jQuery插件formValidator自定义函数扩展功能实例详解
2015/11/25 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
2016/02/21 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
2016/05/25 Javascript
微信小程序-消息提示框实例
2016/11/24 Javascript
vue中计算属性(computed)、methods和watched之间的区别
2017/07/27 Javascript
微信小程序中button组件的边框设置的实例详解
2017/09/27 Javascript
js中this对象用法分析
2018/01/05 Javascript
深入理解JS的事件绑定、事件流模型
2018/05/13 Javascript
详解vue挂载到dom上会发生什么
2019/01/20 Javascript
在vue中使用jsx语法的使用方法
2019/09/30 Javascript
Vue 图片压缩并上传至服务器功能
2020/01/15 Javascript
Python使用中文正则表达式匹配指定中文字符串的方法示例
2017/01/20 Python
利用python将图片转换成excel文档格式
2017/12/30 Python
python入门教程 python入门神图一张
2018/03/05 Python
python操作excel的方法
2018/08/16 Python
浅谈pycharm的xmx和xms设置方法
2018/12/03 Python
Python的互斥锁与信号量详解
2019/09/12 Python
Python自动重新加载模块详解(autoreload module)
2020/04/01 Python
python操作微信自动发消息的实现(微信聊天机器人)
2020/07/14 Python
css3实现一个div设置多张背景图片及background-image属性实例演示
2017/08/10 HTML / CSS
查找廉价航班和发现新目的地:Kiwi.com
2019/02/25 全球购物
澳大利亚在线划船、露营和钓鱼商店:BCF Australia
2020/03/22 全球购物
铁路工务反思材料
2014/02/07 职场文书
竞聘书模板
2014/03/31 职场文书
工业设计毕业生自荐信
2014/04/13 职场文书
经贸专业毕业生求职信范文
2014/05/01 职场文书
工作时间调整通知
2015/04/24 职场文书
欠条样本
2015/07/03 职场文书