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 相关文章推荐
javascript事件模型代码
Jul 01 Javascript
不一样的文字闪烁 轮番闪烁
Nov 11 Javascript
页面中iframe相互传值传参
Dec 13 Javascript
jQuery maxlength文本字数限制插件
Apr 16 Javascript
js不能跳转到上一页面的问题解决方法
Mar 01 Javascript
Javascript玩转继承(一)
May 08 Javascript
Javascript函数式编程语言
Oct 11 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
Dec 03 Javascript
浅析jquery数组删除指定元素的方法:grep()
May 19 Javascript
Vue 单文件中的数据传递示例
Mar 21 Javascript
浅谈关于.vue文件中style的scoped属性
Aug 19 Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
Jun 04 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
冰滴咖啡制作步骤
2021/03/03 冲泡冲煮
DedeCMS dede_channeltype表字段注释
2010/04/07 PHP
关于php中的json_encode()和json_decode()函数的一些说明
2016/11/20 PHP
Laravel学习教程之本地化模块
2017/08/18 PHP
PHP判断json格式是否正确的实现代码
2017/09/20 PHP
WordPress 照片lightbox效果的运用几点
2009/06/22 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
JS两种定义方式的区别、内部原理
2013/11/21 Javascript
jquery form 隐藏的input 选择
2014/04/29 Javascript
JavaScript中的函数重载深入理解
2014/08/04 Javascript
DOM基础教程之模型中的模型节点
2015/01/19 Javascript
jQuery实现布局高宽自适应的简单实例
2016/05/28 Javascript
AngularJs基本特性解析(一)
2016/07/21 Javascript
Vue.js系列之vue-router(上)(3)
2017/01/03 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
详解JS函数防抖
2020/06/05 Javascript
原生JavaScript实现轮播图
2021/01/10 Javascript
Python判断值是否在list或set中的性能对比分析
2016/04/16 Python
详解Python使用tensorflow入门指南
2018/02/09 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Django中反向生成models.py的实例讲解
2018/05/30 Python
Django框架实现逆向解析url的方法
2018/07/04 Python
Python从使用线程到使用async/await的深入讲解
2018/09/16 Python
自定义django admin model表单提交的例子
2019/08/23 Python
Python 异常的捕获、异常的传递与主动抛出异常操作示例
2019/09/23 Python
修改Pandas的行或列的名字(重命名)
2019/12/18 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
加拿大品牌鞋包连锁店:Little Burgundy
2021/02/28 全球购物
如何用JQuery进行表单验证
2013/05/29 面试题
给排水专业应届生求职信
2013/10/12 职场文书
车间工艺员岗位职责
2013/12/09 职场文书
幼儿园中班教学反思
2014/02/10 职场文书
公司成本主管岗位责任制
2014/02/21 职场文书
我的中国心演讲稿
2014/09/04 职场文书
机关单位2016年创先争优活动总结
2016/04/05 职场文书
Unicode中的CJK(中日韩统一表意文字)字符小结
2021/12/06 HTML / CSS