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 相关文章推荐
ExtJs3.0中Store添加 baseParams 的Bug
Mar 10 Javascript
Prototype源码浅析 String部分(二)
Jan 16 Javascript
JS字符串截取函数实例
Dec 27 Javascript
javascript下拉列表中显示树形菜单的实现方法
Nov 17 Javascript
AngularJS 如何在控制台进行错误调试
Jun 07 Javascript
jQuery实现的图片轮播效果完整示例
Sep 12 Javascript
jQuery版AJAX简易封装代码
Sep 14 Javascript
javascript中的深复制详解及实例分析
Dec 29 Javascript
JS+HTML5 FileReader实现文件上传前本地预览功能
Mar 27 Javascript
微信小程序自定义组件
Aug 16 Javascript
ES6 Map结构的应用实例分析
Jun 26 Javascript
JavaScript对象字面量和构造函数原理与用法详解
Apr 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
来自PHP.NET的入门教程
2006/10/09 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
Yii框架中 find findAll 查找出制定的字段的方法对比
2014/09/10 PHP
php查询相似度最高的字符串的方法
2015/03/12 PHP
php使用curl代理实现抓取数据的方法
2017/02/03 PHP
js 调用父窗口的具体实现代码
2013/07/15 Javascript
js报$ is not a function 的问题的解决方法
2014/01/20 Javascript
jQuery的text()方法用法分析
2014/12/20 Javascript
创建、调用JavaScript对象的方法集锦
2014/12/24 Javascript
基于Turn.js 实现翻书效果实例解析
2016/06/20 Javascript
深入分析javascript中的错误处理机制
2016/07/17 Javascript
JS当前页面登录注册框,固定DIV,底层阴影的实例代码
2016/09/29 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
Node.js如何响应Ajax的POST请求并且保存为JSON文件详解
2017/03/10 Javascript
JS实现动态生成html table表格的方法分析
2018/07/11 Javascript
Bootstrap模态对话框中显示动态内容的方法
2018/08/10 Javascript
解决Layui数据表格中checkbox位置不居中的方法
2018/08/15 Javascript
使用koa-log4管理nodeJs日志笔记的使用方法
2018/11/30 NodeJs
小程序的上传文件接口的注意要点解析
2019/09/17 Javascript
javascript前端实现多视频上传
2020/12/13 Javascript
[01:05]主宰至宝剑心之遗
2017/03/16 DOTA
Python爬虫抓取手机APP的传输数据
2016/01/22 Python
Python socket实现简单聊天室
2018/04/01 Python
Python线性拟合实现函数与用法示例
2018/12/13 Python
对python文件读写的缓冲行为详解
2019/02/13 Python
Python Pandas对缺失值的处理方法
2019/09/27 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
video下autoplay属性无效的解决方法(添加muted属性)
2020/05/19 HTML / CSS
高中毕业生生活的自我评价
2013/12/08 职场文书
大学军训感言1500字
2014/03/09 职场文书
暑假学习心得体会
2014/09/02 职场文书
知识就是力量演讲稿
2014/09/13 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
2015年路政工作总结
2015/05/22 职场文书
人生遥控器观后感
2015/06/11 职场文书
MySQL创建高性能索引的全步骤
2021/05/02 MySQL