登录鉴权之Cookie&Session&JWT,nodejs登录鉴权详解、前后端登录鉴权的几种方式、jsonwebtoken是什么
凉菜凉凉 2024-07-24 11:33:01 阅读 72
Cookie&Session
「HTTP 无状态」我们知道,HTTP 是无状态的。也就是说,HTTP 请求方和响应方间无法维护状态,都是一次性的,它不知道前后的请求都发生了什么。但有的场景下,我们需要维护状态。最典型的,一个用户登陆微博,发布、关注、评论,都应是在登录后的用户状态下的。「标记」那解决办法是什么呢?
<code>const express = require("express");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const app = express();
app.use(
session({
secret: "this is session", // 服务器生成 session 的签名
resave: true,
saveUninitialized: true, //强制将为初始化的 session 存储
cookie: {
maxAge: 1000 * 60 * 10,// 过期时间
secure: false, // 为 true 时候表示只有 https 协议才能访问cookie
},
rolling: true, //为 true 表示 超时前刷新,cookie 会重新计时; 为 false 表示在超时前刷新多少次,都是按照第一次刷新开始计时。
store: MongoStore.create({
mongoUrl: 'mongodb://127.0.0.1:27017/lzm_session',
ttl: 1000 * 60 * 10 // 过期时间
}),
})
);
app.use((req,res,next)=>{
if(req.url==="/login"){
next()
return;
}
if(req.session.user){
req.session.garbage = Date();
next();
}else{
res.redirect("/login")
}
})
JSON Web Token (JWT)
(1)介绍
我为什么要保存这可恶的session呢, 只让每个客户端去保存该多好?
当然, 如果一个人的token 被别人偷走了, 那我也没办法, 我也会认为小偷就是合法用户, 这其实和一个人的session id 被别人偷走是一样的。
这样一来, 我就不保存session id 了, 我只是生成token , 然后验证token , 我用我的CPU计算时间获取了我的session 存储空间 !
解除了session id这个负担, 可以说是无事一身轻, 我的机器集群现在可以轻松地做水平扩展, 用户访问量增大, 直接加机器就行。 这种无状态的感觉实在是太好了!
缺点:
占带宽,正常情况下要比 session_id 更大,需要消耗更多流量,挤占更多带宽,假如你的网站每月有 10 万次的浏览器,就意味着要多开销几十兆的流量。听起来并不多,但日积月累也是不小一笔开销。实际上,许多人会在 JWT 中存储的信息会更多;无法在服务端注销,那么久很难解决劫持问题;性能问题,JWT 的卖点之一就是加密签名,由于这个特性,接收方得以验证 JWT 是否有效且被信任。对于有着严格性能要求的 Web 应用,这并不理想,尤其对于单线程环境。
注意:
CSRF攻击的原因是浏览器会自动带上cookie,而不会带上token;
以CSRF攻击为例:
cookie:用户点击了链接,cookie未失效,导致发起请求后后端以为是用户正常操作,于是进行扣款操作;
token:用户点击链接,由于浏览器不会自动带上token,所以即使发了请求,后端的token验证不会通过,所以不会进行扣款操作;
(2)实现
<code>//jsonwebtoken 封装
const jsonwebtoken = require("jsonwebtoken")
const secret = "lzm"
const JWT = {
generate(value,exprires){
return jsonwebtoken.sign(value,secret,{ expiresIn:exprires})
},
verify(token){
try{
return jsonwebtoken.verify(token,secret)
}catch(e){
return false
}
}
}
module.exports = JWT
//node中间件校验
app.use((req,res,next)=>{
// 如果token有效 ,next()
// 如果token过期了, 返回401错误
if(req.url==="/login"){
next()
return;
}
const token = req.headers["authorization"].split(" ")[1]
if(token){
var payload = JWT.verify(token)
// console.log(payload)
if(payload){
const newToken = JWT.generate({
_id:payload._id,
username:payload.username
},"1d")
res.header("Authorization",newToken)
next()
}else{
res.status(401).send({ errCode:"-1",errorInfo:"token过期"})
}
}
})
//生成token
const token = JWT.generate({
_id: result[0]._id,
username: result[0].username
}, "1d")
res.header("Authorization", token)
//前端拦截
/*
* @作者: liangzm
*/
import axios from 'axios'
// Add a request interceptor
axios.interceptors.request.use(function (config) {
const token = localStorage.getItem("token")
config.headers.Authorization = `Bearer ${ token}`
return config;
}, function (error) {
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
const { authorization } = response.headers
authorization && localStorage.setItem("token",authorization)
return response;
}, function (error) {
const { status} = error.response
if(status===401){
localStorage.removeItem("token")
window.location.href="/login"code>
}
return Promise.reject(error);
});
下一篇: 解决uniapp开发抖音小程序video-player覆盖问题,超详细教程,前端相关操作,已成功上线产品
本文标签
登录鉴权之Cookie&Session&JWT nodejs登录鉴权详解、前后端登录鉴权的几种方式、jsonwebtoken是什么
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。