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 相关文章推荐
js 对象是否存在判断
Jul 15 Javascript
JQuery.ajax传递中文参数的解决方法 推荐
Mar 28 Javascript
VBS通过WMI监视注册表变动的代码
Oct 27 Javascript
图片Slider 带左右按钮的js示例
Aug 30 Javascript
浅析JQuery UI Dialog的样式设置问题
Dec 18 Javascript
用IE重起计算机或者关机的示例代码
Mar 10 Javascript
js中实现多态采用和继承类似的方法
Aug 22 Javascript
JavaScript中split() 使用方法汇总
Apr 17 Javascript
jQuery+css3实现Ajax点击后动态删除功能的方法
Aug 10 Javascript
vue2实现数据请求显示loading图
Nov 28 Javascript
vue路由前进后退动画效果的实现代码
Dec 10 Javascript
使用vue-cli3+typescript的项目模板创建工程的教程
Feb 28 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 咖啡文化
PHP中对数据库操作的封装
2006/10/09 PHP
php REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
php一句话cmdshell新型 (非一句话木马)
2009/04/18 PHP
用PHP读取和编写XML DOM的实现代码
2011/02/03 PHP
Laravel模板引擎Blade中section的一些标签的区别介绍
2015/02/10 PHP
php获取文章内容第一张图片的方法示例
2017/07/03 PHP
php的对象传值与引用传值代码实例讲解
2021/02/26 PHP
script标签属性type与language使用选择
2012/12/02 Javascript
js实现全屏漂浮广告移入光标停止移动
2013/12/02 Javascript
jquery动态增加删减表格行特效
2015/11/20 Javascript
jQuery实现的导航下拉菜单效果
2016/07/04 Javascript
简单封装js的dom查询实例代码
2016/07/08 Javascript
JavaScript提高网站性能优化的建议(二)
2016/07/24 Javascript
bootstrap导航栏、下拉菜单、表单的简单应用实例解析
2017/01/06 Javascript
vue 路由页面之间实现用手指进行滑动的方法
2018/02/23 Javascript
Vue.js 中的 v-cloak 指令及使用详解
2018/11/19 Javascript
es6 symbol的实现方法示例
2019/04/02 Javascript
[05:37]DOTA2-DPC中国联赛 正赛 Elephant vs iG 选手采访
2021/03/11 DOTA
python中迭代器(iterator)用法实例分析
2015/04/29 Python
python读取和保存图片5种方法对比
2018/09/12 Python
Python字符串中添加、插入特定字符的方法
2019/09/10 Python
Python使用指定字符长度切分数据示例
2019/12/05 Python
python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例
2020/03/19 Python
Python面向对象程序设计之继承、多态原理与用法详解
2020/03/23 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
2020/05/11 Python
windows10在visual studio2019下配置使用openCV4.3.0
2020/07/14 Python
Python 实现PS滤镜中的径向模糊特效
2020/12/03 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
意大利包包和行李箱销售网站:Bagaglio.it
2021/03/02 全球购物
感恩节活动策划方案
2014/05/16 职场文书
云冈石窟导游词
2015/02/04 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
校运会新闻稿
2015/07/17 职场文书
Go语言中的UTF-8实现
2021/04/26 Golang
用 Python 元类的特性实现 ORM 框架
2021/05/19 Python