express框架下使用session的方法


Posted in Javascript onJuly 31, 2019

上一遍文章说了cookie的不足,提到使用session是解决缺点的一个方法。这遍文章说说怎么使用session.作者使用了文件保存session的方法。若用别保存方式(内存、数据库)也行,记得使用相应的模块。
下面从使用内存存储和文件存储的2个方法分别说明。

内存存储session

实现过程

// app.js
// 引入express-session
var session = require('express-session')
// 为应用绑定session中间件
app.use(session({
  name: 'session-id',
  secret: '12345-67890',
  saveUninitialized: false,
  resave: false
}))

查看结果

router.get('/session/first', (req, res, next) => {
 let s = req.session
 console.log(s)
 res.send(s)
})

express框架下使用session的方法

使用

使用这个方法做一个demo.比如显示浏览次数。

router.get('/session/view', (req, res, next) => {
 let s = req.session
 if (req.session.views) {
  req.session.views++
  res.send(`views: ${req.session.views} time.`)
 } else {
  req.session.views = 1
  res.send('views: 0')
 }
})

express框架下使用session的方法

我发现在操作session后,会在根目录下创建一个session目录,里面保存了session.

文件存储session

相对于内存存储session不同在于保存session的位置不同。内存存储方式是把session保存在session里。对于后台服务会占用大量内存,这种方法肯定不行。文件存储方式是把session保存在文件夹里。听说还有一种叫数据库保存。

install

要使用文件存储session需要安装session-file-store

npm i express-session session-file-store

使用文件存储

// app.js
var session = require('express-session')
var FileStore = require('session-file-store')(session) // 引入 
// 在express-session中使用
app.use(session({
 name: 'session-id',
 secret: '12345-67890',
 saveUninitialized: false,
 resave: false,
 store: new FileStore() // 指明使用文件存储
}))

注册、登录、登录验证和登出

这部分需要bodyParser mongoose模块。记得安装。

1. 创建数据库连接。

连接了数据库就可以把用户数据放在数据库里。

// app.js
const mongoose = require('mongoose')
const url = 'mongoodb://localhost:27017/confusion'
const connect = mongoose.connect(url, {useNewUrlParser: true, useCreateIndex: true})
connest.then(db => {
 console.log('Connect correct to server')
}, err => {console.log(err)})

2. 创建user的model,用于连接数据库。

在项目根目录下创建models目录,再创建user.js。下面定义了user的model

// @/models/user.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
User = new Schema({
 username: {
  type: String,
  required: true,
  unique: true
 },
 password: {
  type: String,
  required: true
 },
 admin: {
  type: Boolean,
  default: false
 }
})
module.exports = mongoose.model('User', User)

3. 创建注册的接口。

注册的接口
  是否已经存在用户------存在------>不重复创建. 
      |-----------不存在----->创建用户

// @/routes/users.js
// /session/first /session/view 注释了或删除了。
// 该文件在app.user(session(...))之前,所以得不到req.session
// // 查看session
// router.get('/session/first', (req, res, next) => {
//  let s = req.session
//  console.log(s)
//  res.send(s)
// })
// // 在session里保存浏览次数
// router.get('/session/view', (req, res, next) => {
//  let s = req.session
//  if (req.session.views) {
//   req.session.views++
//   res.send(`views: ${req.session.views} time.`)
//  } else {
//   req.session.views = 1
//   res.send('views: 1')
//  }
// })

router.post('/signup', (req, res, next) => {
 console.log(req.body)
 User.findOne({username: req.body.username}).then(user => {
  if (user === null) {
   return User.create({
    username: req.body.username,
    password: req.body.password
   })
  } else {
   var err = new Error(`User ${req.body.username} already exist!`)
   err.status = 403
   next(err)
  }
 }).then(user => {
  res.statusCode = 200
  res.json({status: 'registration successful', user: user})
 }).catch(err => {
  res.send(err)
 })
})

4. 创建登录的接口。

登录的接口https://github.com/feigebaobei/nodejs/tree/master/node-session
  是否已经登录------登录------>不做事 
    |-----------没登录----->验证username/password是否正确.----正确---->设置已经登录 
                    |----------------------不正确---->返回错误

router.post('/login', (req, res, next) => {
 if (req.session.auth) { // 以req.session.auth为标记,标记是否已经通过登录验证
  res.statusCode = 200
  res.send('You are already authenticated')
 } else {
  User.findOne({username: req.body.username}).then(user => {
   if (user) {
    if (user.password !== req.body.password) {
     var err = new Error(`password error`)
     err.status = 403
     next(err)
    } else {
     req.session.auth = true // 登录成功设置标记为true
     res.statusCode = 200
     res.send('login successful')
    }
   } else { // 没用指定用户
    var err = new Error(`User ${req.body.username} does not exist!`)
    err.status = 403
    next(err)
   }
  // }).catch(err => next(err))
  }).catch(err => {
   res.send(err)
  })
 }
})

5. 创建登出的接口。

router.get('/logout', (req, res, next) => {
 if (req.session) {
  req.session.destroy() // 删除session
  res.clearCookie('session-id') // 删除cookie
  res.send('登出成功。重定向的事让前端做')
 } else {
  var err = new Error('you are not logged in!')
  err.status = 403
  next(err)
 }
})

6. 登录后才可访问的接口

// @/routes/news.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
 res.render('index', { title: 'Express' });
});
module.exports = router;

7. 编写登录验证的中间件。注意登录接口、登录验证中间件、登录后才可访问的接口的次序。

// app.js
// 1.引入路由
var index = require('./routes/index');
var users = require('./routes/users');
var news = require('./routes/news');
// 2.挂载session中间件
app.use(session({
 name: 'session-id',
 secret: '12345-67890',
 saveUninitialized: false,
 resave: false,
 store: new FileStore()
}))
// 3.挂载不需要登录验证的路由
app.use('/', index)
app.use('/users', users)
// 4.定义验证登录函数
let authFn = (req, res, next) => {
 console.log(req.session)
 if (req.session.auth) {
  next()
 } else {
  var err = new Error('You are not authenticated!')
  err.status = 403
  next(err)
 }
}
// 5.挂载需要登录验证的路由
app.use('/news', news)

总结

这个例子只诠释了简单的登录、验证登录、登出功能。下面是本文用到的js模块(express-session, session-file-store, mongoose)在npm上都能找到。完整代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
Feb 14 Javascript
使用jquery+CSS实现控制打印样式
Dec 31 Javascript
JavaScript判断页面加载完之后再执行预定函数的技巧
May 17 Javascript
Javascript小技能总结(推荐)
Jun 02 Javascript
Angularjs 实现分页功能及示例代码
Sep 14 Javascript
深入理解JS中的Function.prototype.bind()方法
Oct 11 Javascript
jQuery.ajax向后台传递数组问题的解决方法
May 12 jQuery
vue2.0的contextmenu右键弹出菜单的实例代码
Jul 24 Javascript
Angular6 正则表达式允许输入部分中文字符
Sep 10 Javascript
详解小程序循环require之坑
Mar 08 Javascript
通过JS运行机制的角度说说作用域
Mar 12 Javascript
vue-cli3 热更新配置操作
Sep 18 Javascript
ES6中异步对象Promise用法详解
Jul 31 #Javascript
JS实现在线ps功能详解
Jul 31 #Javascript
ES6中定义类和对象的方法示例
Jul 31 #Javascript
Vue+Koa2 打包后进行线上部署的教程详解
Jul 31 #Javascript
简述vue-cli中chainWebpack的使用方法
Jul 30 #Javascript
vue实现中部导航栏布局功能
Jul 30 #Javascript
js定义类的方法示例【ES5与ES6】
Jul 30 #Javascript
You might like
apache php mysql开发环境安装教程
2016/07/28 PHP
弹出模态框modal的实现方法及实例
2017/09/19 PHP
js loading加载效果实现代码
2009/11/24 Javascript
jquery isType() 类型判断代码
2011/02/14 Javascript
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
JQ获取动态加载的图片大小的正确方法分享
2013/11/08 Javascript
JavaScript函数柯里化详解
2016/04/29 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
自动适应iframe右边的高度
2016/12/22 Javascript
JS中如何实现点击a标签返回页面顶部的问题
2017/01/19 Javascript
Bootstarp基本模版学习教程
2017/02/01 Javascript
详解Vue单元测试Karma+Mocha学习笔记
2018/01/31 Javascript
[42:04]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第一局
2016/03/03 DOTA
[02:36]DOTA2上海特锦赛 回忆电竞生涯的重要瞬间
2016/03/25 DOTA
[06:06]2018DOTA2亚洲邀请赛主赛事第四日战况回顾 全明星赛欢乐上演
2018/04/07 DOTA
Python脚本判断 Linux 是否运行在虚拟机上
2015/04/25 Python
python发送邮件功能实现代码
2016/07/15 Python
python爬虫之模拟登陆csdn的实例代码
2018/05/18 Python
[机器视觉]使用python自动识别验证码详解
2019/05/16 Python
pandas统计重复值次数的方法实现
2021/02/20 Python
关于html字符串正则判断和匹配的具体使用
2019/12/12 HTML / CSS
文言文形式的学生求职信
2013/12/03 职场文书
党的群众路线批评与自我批评范文
2014/10/16 职场文书
2014年后勤管理工作总结
2014/12/01 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
小学家长通知书评语
2014/12/31 职场文书
扬州个园导游词
2015/02/06 职场文书
西岭雪山导游词
2015/02/06 职场文书
2015年大学生党员承诺书
2015/04/27 职场文书
2015年政务公开工作总结
2015/05/19 职场文书
毕业欢送会致辞
2015/07/29 职场文书
客户答谢会致辞
2015/07/30 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书
护理自荐信
2019/05/14 职场文书
高考要来啦!用Python爬取历年高考数据并分析
2021/06/03 Python
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB