express express-session的使用小结
简介
express-session是express中的一个处理session的中间件,可以说是express中最常见的中间件之一了.
由于会话管理依赖cookie的使用,所以它的api中有很多用于控制cookie的部分.
总的来说express-session有如下的特点:
- session管理(基本功能)
- cookie签名
- 可替换持久储存模块
本文中使用的版本为1.15.6.
安装
npminstallexpress-session--save
引入&使用
constexpress=require('express');
constapp=newexpress();
constexpressSession=require('express-session');
//使用express-session
app.use(expressSession({
secret:'helloworld',//cookie签名这个属性是必须的具体配置和`cookie-parser`一样
saveUninitialized:true,//是否自动初始化默认为true
resave:false,//当用户session无变化的时候依然自动保存
cookie:{//cookie的信息具体操作和`cookie-parser`一样
maxAge:1800000//30分钟后过期
},
rolling:true//每次请求的时候覆写cookie
}))
会话简介
在express-session文档中有如下的一句说明:
NoteSessiondataisnotsavedinthecookieitself,justthesessionID.Sessiondataisstoredserver-side.
Session中包含的数据不会保存在cookie中,仅仅是在cookie中保存了一个SessionId而已.实际的session的数据保存在服务端.
简单理解就是一个Map,键对应的是sessionid值保存在cookie中,值对应的是用户保存在服务端的数据.
api介绍
参数
创建express-cookie参数基本分为两种.
- 针对于cookie的设置
- 针对于express-session的设置
cookie设置一览:
app.use(expressSession({
secret:'helloworld',//cookie签名必须有否则会报错
cookie:{
domain:<参数>,
expires:<参数>,
httpOnly:<参数>,
path:<参数>,
sameSite:<参数>,
secure:<参数>,
maxAge:1800000
}
}));
而这些对应的参数就是服务端对于cookie的写入参数,至于各个参数是什么意思参考下面的文章:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie
express-session部分设置:
app.use(expressSession({
secret:'helloworld',//cookie签名必须有否则会报错
genid:function(request){//用于替换掉默认ID生成的函数第一个参数为reqeust
return'随机id'
},
name:'connect.sid',//每次响应中向cookie中起始的内容,默认起始为`connect.sid`,
proxy:true,//对于cookie使用secure后,在传递的过程中相信反向代理服务器,默认为undefined只相信正向代理
resave:true,//在一次会话中无论是否session被改变都会进行强制的储存
rolling:true,//在每次会话中的响应中都覆写一次cookie,重置倒计时
saveUninitialized:true,//将一个新创建还未修改的会话进行储存,默认为true
store:object//一个储存对象,默认使用的是`MemoryStore`这个存储器
unset:'keep'//控制没有设置`req.session`时候的行为(使用delete删除或者赋值null),默认'keep'会话期间不会保留,'destroy'会话完成后删除.
}));
方法
在request.session上挂载的session对象,除了有你添加的内容外,还有默认的方法存在:
req.session.regenerate(function(err){
//调用这个方法从新生成一个新的会话,完成后触发
})
req.session.destroy(function(err){
//删除这个会话,完成后触发
})
req.session.reload(function(err){
//从新加载session数据,完成后触发回调
})
req.session.save(function(err){
//使用当前内存中的数据保存到储存器中
//默认在会话结束的时候就会自动调用这个方法
})
req.session.touch()//更新cookie中的maxAge,一般不需要手动操作,交由中间件
属性
同样的在session实例上也有很多属性:
req.session.id//保存唯一的会话id值,不可修改 req.session.cookie//以键值对的形式保存cookie的原始数据 req.session.cookie.maxAge//以毫秒的形式返回剩余存活时间 req.sessionID//保存唯一的会话id,只读
一个简单的例子
一个简单的登录例子:
constexpress=require('express');
constapp=newexpress();
constexpressSession=require('express-session');
constuserDb=newMap();
app.use(expressSession({
secret:'helloworld',
saveUninitialized:true,
resave:false,
cookie:{
maxAge:1800000
},
rolling:true,
}));
app.get('/login',(request,response)=>{
const
id=request.query.id,
pwd=request.query.pwd;
if(id&&pwd){
if(userDb.has(id+pwd)){
response.send('该用户已登录');
}else{
request.session.userId=id+pwd;
userDb.set(id+pwd,id);
response.redirect('/');
}
}else{
response.send('请输入正确的帐号和密码');
}
});
app.get('/logout',(request,response)=>{
constuserId=request.session.userId;
request.session.destroy((err)=>{
if(err||!userDb.has(userId)){
response.send('登出失败');
}else{
userDb.delete(userId);
response.send('登出成功');
}
});
});
app.get('/',(request,response)=>{
if(request.session.userId&&userDb.has(request.session.userId)){
response.send(`欢迎回来${userDb.get(request.session.userId)}`);
}else{
response.send('还未登录');
}
});
app.use((request,response)=>{
response.send('404notfound');
});
app.listen(8888,'127.0.0.1');
在浏览器中依次输入以下url来模拟登录行为:
localhost:8888/ localhost:8888/login?id=ASCll&pwd=123456 localhost:8888/ localhost:8888/logout localhost:8888/
暗坑
我在chrome浏览器下运行上面的例子多次后发现一个问题,浏览器会进行预读取网页来提高性能,也就是说在浏览器中当我url输入到如下的地方时:
localhost:8888/logo
根据我之间多次进入这个页面浏览器会提前访问这个页面localhost:8888/logout,而导致服务器直接删除session等到真正进入到页面的时候已经是第二次加载页面了,导致每次登出都显示失败.
希望有经验的朋友能给出一个合理的解决方案.
注意
当express-session和cookie-parser一起使用的时候对于cookie的签名必须一致.
express-session的存储实例是可以更换的,默认使用MemoryStore只适合于测试和开发使用,生产环境必须要使用其他的储存实例,否则会出现内存碎片问题,在官方文档中给出了已经实现的接口,可以对接redis以及mongodb等数据库.
该列表在官方文档的最后:
npm地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。