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多重继承示例
Mar 13 Javascript
JavaScript 对Cookie 操作的封装小结
Dec 31 Javascript
使用JavaScript动态设置样式实现代码及演示动画
Jan 25 Javascript
js菜单点击显示或隐藏效果的简单实例
Jan 13 Javascript
Bootstrap基础学习
Jun 16 Javascript
jQuery图片左右滚动代码 有左右按钮实例
Jun 20 Javascript
jQuery+CSS3实现四种应用广泛的导航条制作实例详解
Sep 17 Javascript
微信小程序(应用号)开发新闻客户端实例
Oct 24 Javascript
Angular2数据绑定详解
Apr 18 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
Dec 25 Javascript
关于vue里页面的缓存详解
Nov 04 Javascript
基于openlayers实现角度测量功能
Sep 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
ThinkPHP设置禁止百度等搜索引擎转码(简单实用)
2016/02/15 PHP
PHP实现 APP端微信支付功能
2018/06/22 PHP
JQuery扩展插件Validate—6 radio、checkbox、select的验证
2011/09/05 Javascript
js数组的操作详解
2013/03/27 Javascript
基于jquery插件制作左右按钮与标题文字图片切换效果
2013/11/07 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
2014/02/12 Javascript
javascript实现图片上传前台页面
2015/08/18 Javascript
jQuery插件Timelinr 实现时间轴特效
2015/10/04 Javascript
AngularJS 指令详细介绍
2016/07/27 Javascript
浅谈JavaScript的闭包函数
2016/12/08 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
2017/02/15 Javascript
React复制到剪贴板的示例代码
2017/08/22 Javascript
nodejs实现的连接MySQL数据库功能示例
2018/01/25 NodeJs
Angular 封装并发布组件的方法示例
2018/04/19 Javascript
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
vue组件实现进度条效果
2018/06/06 Javascript
微信小程序中使用ECharts 异步加载数据实现图表功能
2018/07/13 Javascript
深入浅出了解Node.js Streams
2019/05/27 Javascript
layer.open 子页面弹出层向父页面传输数据的例子
2019/09/26 Javascript
微信小程序去除左上角返回键的实现方法
2020/03/06 Javascript
[40:19]2018完美盛典CS.GO表演赛
2018/12/17 DOTA
二种python发送邮件实例讲解(python发邮件附件可以使用email模块实现)
2013/12/03 Python
python实现简单的单变量线性回归方法
2018/11/08 Python
django做form表单的数据验证过程详解
2019/07/26 Python
用Cython加速Python到“起飞”(推荐)
2019/08/01 Python
python实现机器人卡牌
2019/10/06 Python
Django中modelform组件实例用法总结
2020/02/10 Python
Python如何telnet到网络设备
2021/02/18 Python
python如何发送带有附件、正文为HTML的邮件
2021/02/27 Python
以设计师精品品质提供快速时尚:Mostata
2019/05/10 全球购物
JENNIFER BEHR官网:各种耳环和发饰
2020/06/07 全球购物
JavaScript实现页面动态验证码的实现示例
2021/03/23 Javascript
暑期培训随笔感言
2014/03/10 职场文书
2019安全宣传标语大全
2019/08/14 职场文书
Python Matplotlib绘制条形图的全过程
2021/10/24 Python
详解Python内置模块Collections
2022/03/22 Python