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 相关文章推荐
treepanel动态加载数据实现代码
Dec 15 Javascript
动态加载script文件的两种方法
Aug 15 Javascript
js实现幻灯片效果(基于jquery插件)
Nov 05 Javascript
javascript生成随机大小写字母的方法
Feb 20 Javascript
javascript框架设计读书笔记之字符串的扩展和修复
Dec 02 Javascript
JS实现单行文字不间断向上滚动的方法
Jan 29 Javascript
基于Vuejs框架实现翻页组件
Jun 29 Javascript
javaScript 连接打印机,打印小票的实例
Dec 29 Javascript
vue.js根据代码运行环境选择baseurl的方法
Feb 28 Javascript
webpack公共组件引用路径简化小技巧
Jun 15 Javascript
Vue通过for循环随机生成不同的颜色或随机数的实例
Nov 09 Javascript
关于javascript中的promise的用法和注意事项(推荐)
Jan 15 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生成唯一的订单函数分享
2015/02/02 PHP
Thinkphp5框架简单实现钩子(Hook)行为的方法示例
2019/09/03 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
无缝滚动改进版支持上下左右滚动(封装成函数)
2012/12/04 Javascript
非常漂亮的JS+CSS图片幻灯切换特效
2013/11/20 Javascript
jquery使用淘宝接口跨域查询手机号码归属地实例
2013/11/28 Javascript
jQuery中ajax的使用与缓存问题的解决方法
2013/12/19 Javascript
JavaScript使ifram跨域相互访问及与PHP通信的实例
2016/03/03 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
2017/09/11 Javascript
微信小程序实现自定义加载图标功能
2018/07/19 Javascript
vue实现商品加减计算总价的实例代码
2018/08/12 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
[00:53]2015国际邀请赛 中国区预选赛一触即发
2015/05/14 DOTA
[04:44]DOTA2西游记战队视频彩蛋流出 师徒开黑巧遇林书豪
2016/08/03 DOTA
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
[01:20:38]完美世界DOTA2联赛 GXR vs IO 第一场 11.07
2020/11/09 DOTA
深入分析python数据挖掘 Json结构分析
2018/04/21 Python
python定向爬虫校园论坛帖子信息
2018/07/23 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
基于python爬取链家二手房信息代码示例
2020/10/21 Python
python安装及变量名介绍详解
2020/12/12 Python
不同浏览器对CSS3和HTML5的支持状况
2009/10/31 HTML / CSS
详解利用canvas实现环形进度条的方法
2019/06/12 HTML / CSS
HTML5 在canvas中绘制矩形附效果图
2014/06/23 HTML / CSS
通过canvas转换颜色为RGBA格式及性能问题的解决
2019/11/22 HTML / CSS
航空大学应届生求职信
2013/11/10 职场文书
市场营销专业求职信
2014/06/17 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
村党建工作汇报材料
2014/11/02 职场文书
2014年双拥工作总结
2014/11/21 职场文书
作文批改评语
2014/12/25 职场文书
Nginx优化服务之网页压缩的实现方法
2021/03/31 Servers
Python绘制地图神器folium的新人入门指南
2021/05/23 Python
JavaScript中MutationObServer监听DOM元素详情
2021/11/27 Javascript
使用Redis实现分布式锁的方法
2022/06/16 Redis