无障碍网站建设,广告平台对接,wordpress文章页幻灯片,品牌策划岗位职责Session-Cookie 鉴权
cookie介绍
Cookie 存储在客户端#xff0c;可随意篡改#xff0c;不安全有大小限制#xff0c;最大为 4kb有数量限制#xff0c;一般一个浏览器对于一个网站只能存不超过 20 个 Cookie#xff0c;浏览器一般只允许存放 300个 CookieCookie 是不可跨…Session-Cookie 鉴权
cookie介绍
Cookie 存储在客户端可随意篡改不安全有大小限制最大为 4kb有数量限制一般一个浏览器对于一个网站只能存不超过 20 个 Cookie浏览器一般只允许存放 300个 CookieCookie 是不可跨域的但是一级域名和二级域名是允许共享使用的靠的是 domain
session介绍
当浏览器访问服务器并发送第一次请求时服务器端会创建一个session对象生成一个类似于 key,value的键值对然后将key(cookie)返回到浏览器(客户)端浏览器下次再访问时携带key(cookie) 找到对应的session(value)。 客户的信息都保存在session中
流程图解 代码实践
技术栈
前端React后端Express MongoDB
后端部分
1.安装express-session
npm install express-session --save
2.在路由前配置中间件
//配置中间件
app.use(session({secret: this is Chris Wu, // 可以随便写。 一个 String 类型的字符串作为服务器端生成 session 的签名name: session_id /*保存在本地cookie的一个名字 默认connect.sid可以不设置*/,resave: false /*强制保存 session 即使它并没有变化,。默认为 true。建议设置成 false。*/,saveUninitialized: true, //强制将未初始化的 session 存储。默认值是true建议设置成truecookie: {maxAge: 1000 * 30 * 60/*过期时间*/,secure: false} /*secure https这样的情况才可以访问cookie*/,//设置过期时间比如是30分钟只要游览页面30分钟没有操作的话在过期rolling: true, //在每次请求时强行设置 cookie这将重置 cookie 过期时间默认false})
); 3.在用户登录接口中设置session req.session.user username
// 用户登录
const signin async (req, res, next) {// 前端传过来的用户名和密码const { username, password } req.body// 从数据库中查询用户let result await usersModel.findUser(username) // 验证用户是否是合法用户if (result) {// 设置 sessionreq.session.user username;res.send({code:1,data:登陆成功!});} else {res.send({code:0,data:用户名或密码错误!});}
} 登录成功后我们可以打开浏览器F12的Application中的Cookies查看,已经生成了一个key为session_id的cookie 4.在需要登录状态下的请求我们可以通过req.session.user判断例如一个检查登录的接口
app.get(/check, function (req, res) {//获取sesssionif (req.session.user) {/*获取*/res.send(你好 req.session.user 欢迎回来);} else {// 获取不到就返回未登录信息给前端前端跳到登录页面res.send({errCode: 10001,msg:未登录});}
}); 5.如果想销毁session app.get(/logout,function(req,res){//销毁req.session.destroy(function(err){console.log(err);})res.send(退出登录成功);}); 到这一步后端的鉴权已初步完成
但是设想一下cookie中的maxAge只设置了10秒用户每一次操作的间隔会很长再想操作页面时cookie已过期那又需要重新登录这样体验感会很差
6.所以我们可以设置一个全局的中间件在每次请求时更新session
这个中间件需要放在路由前和session中间件后
app.use((req,res,next){if(req.url.includes(signin)){next();return;}console.log(req.session)if(req.session.user){// 通过new Date()更新sessionreq.session.mydate new Date();next();}else {res.status(401).send({code:0})}
}) 7.session可以结合数据库做持久化操作当服务器挂掉时也不会导致某些客户信息丢失。 我使用的是MongoDB
安装connect-mongo引入并直接在session中间件中间件中添加如下配置
注意cookie的过期时间和数据库中的过期时间要一致
const MongStore require(connect-mongo)
//配置中间件
app.use(session({secret: this is string key, name: session_id resave: false saveUninitialized: true, cookie: {maxAge: 1000 * 30 * 60secure: false} rolling: true, store: MongStore.create({mongoUrl:mongodb://localhost:27017/react_login_session,ttl:1000 * 60 *30})})
); 到这里后端的工作已全部完成啦
前端部分
1.登录部分 2.axios的封装 由于sessionID保存在cookie中每次请求会直接带上cookie使用请求拦截中无需操作
但是如果cookie失效后端会返回401错误码所以在请求拦截中需要判断返回登录页
这里由于不太熟悉React的路由哈哈哈所以直接用 window.location.href 跳转登录页了 到这一步前端的工作也完成了
坑
这期间遇到的坑竟然是跨域问题
问题
一开始我为了方便就用了npm i cors直接调用这个中间件解决跨域
请求时session中保存的字段消失了
然后我通过打印req.session发现复杂请求会先发一次option预检再发送真实的请求这期间session中的字段就会消失 解决
需要在请求头中加上这两行
res.header(Access-Control-Allow-Origin”,http://locallhost:3000) 不能为*了必须指定
response.setHeader(Access-Control-Allow-Credentials,true);//是否支持cookie跨域 当然也可以前端利用webpack中的代理解决跨域就避免了这个坑
END
session-cookie鉴权的操作并不难可是Session 存储在服务端增大了服务端的开销用户量大的时候会大大降低服务器性能并且非常不安全Cookie 将数据暴露在浏览器中增加了数据被盗的风险容易被 CSRF 等攻击所以下一篇文章将介绍JWT的操作给大家希望这篇文章可以帮助到有需要的小伙伴有问题可以在评论区留言或私信我
最后
最近还整理一份JavaScript与ES的笔记一共25个重要的知识点对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识提升工作效率。 有需要的小伙伴可以点击下方卡片领取无偿分享