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 相关文章推荐
学习ExtJS form布局
Oct 08 Javascript
让你的博客飘雪花超出屏幕依然看得见
Jan 04 Javascript
jQuery ajax dataType值为text json探索分享
Sep 23 Javascript
Jquery AJAX POST与GET之间的区别
Nov 14 Javascript
javascript中的Base64、UTF8编码与解码详解
Mar 18 Javascript
jQuery实现伪分页的方法分享
Feb 17 Javascript
详解Vue.js搭建路由报错 router.map is not a function
Jun 27 Javascript
史上最全JavaScript常用的简写技巧(推荐)
Aug 17 Javascript
vue后台管理之动态加载路由的方法
Aug 13 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
May 30 jQuery
JavaScript实现动态生成表格
Aug 02 Javascript
JS如何调用WebAssembly编译出来的.wasm文件
Nov 05 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
Window下PHP三种运行方式图文详解
2013/06/11 PHP
PHP实现批量生成App各种尺寸Logo
2015/03/19 PHP
CodeIgniter控制器之业务逻辑实例分析
2016/01/20 PHP
PHP根据session与cookie用户登录状态操作类的代码
2016/05/13 PHP
php 防止表单重复提交两种实现方法
2016/11/03 PHP
JavaScript 入门·JavaScript 具有全范围的运算符
2007/10/01 Javascript
JavaScript 图像动画的小demo
2012/05/23 Javascript
JavaScript数字和字符串转换示例
2014/03/26 Javascript
JavaScript利用append添加元素报错的解决方法
2014/07/01 Javascript
jQuery实现的分子运动小球碰撞效果
2016/01/27 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
js正则表达式验证密码强度【推荐】
2017/03/03 Javascript
weex里Vuex state使用storage持久化详解
2017/09/09 Javascript
关于vue面试题汇总
2018/03/20 Javascript
JS实现的透明度渐变动画效果示例
2018/04/28 Javascript
超轻量级的js时间库miment使用解析
2019/08/02 Javascript
Vue3 中的数据侦测的实现
2019/10/09 Javascript
微信小程序页面渲染实现方法
2019/11/06 Javascript
vue中destroyed方法的使用说明
2020/07/21 Javascript
Python中turtle库的使用实例
2019/09/09 Python
python对XML文件的操作实现代码
2020/03/27 Python
plt.figure()参数使用详解及运行演示
2021/01/08 Python
利用CSS3把图片变成灰色模式的实例代码
2016/09/06 HTML / CSS
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
行政经理的岗位职责
2013/11/23 职场文书
年度考核评语
2014/01/19 职场文书
无故旷工检讨书
2014/01/26 职场文书
技校学生个人职业生涯规划范文
2014/03/03 职场文书
2014医学院领导干部四风对照检查材料思想汇报
2014/09/16 职场文书
2014年乡镇卫生院工作总结
2014/11/24 职场文书
医务人员医德考评自我评价
2015/03/03 职场文书
创业计划书之面包店
2019/09/17 职场文书
2019年图书室自查报告范本
2019/10/12 职场文书
使用css样式设计一个简单的html登陆界面的实现
2021/03/30 HTML / CSS
Java方法重载和方法重写的区别到底在哪?
2021/06/11 Java/Android
python神经网络学习 使用Keras进行回归运算
2022/05/04 Python