jwt权限控制简单总结(乡村意见簿-vue-express-mongdb)

1、JWT 是什么

JWT = JSON Web Token 一段轻量、自包含、防篡改 的字符串,用于在前后端 / 服务之间安全传递用户身份信息

核心特点

  1. 无状态、不用存 Session服务端不需要在内存 / Redis 存用户会话,所有信息都在 token 里。
  2. 跨域 / 分布式友好不依赖 Cookie,天然适合前后端分离、微服务、多域名场景。
  3. 前端存储,每次请求带上 一般存在 localStorage /sessionStorage/ Cookie,通过 axios 拦截器在请求头(如 Authorization: Bearer <token>)传给后端。
  4. 内容 Base64 编码,可解码,不加密
    • 载荷(payload)任何人都能看见
    • 不能存密码等敏感信息
  5. 签名防篡改服务端用密钥签名,只要密钥不泄露,token 就无法伪造 / 篡改。

前端在axios/index统一配置的请求拦截器:

javascript 复制代码
service.interceptors.request.use(
    function (config) {
        console.log("axios拦截器发送请求")
        let userStr = sessionStorage.getItem('cur_user');
        if(userStr){
            let user = JSON.parse(userStr);
            config.headers.Authorization = `Bearer ` + user.token;
        }
        return config;
    }

)

2. JWT 由三部分组成(固定结构)

bash 复制代码
Header.Payload.Signature

① Header(头)

  • 说明算法:HS256
  • 说明类型:JWT
  • 公开、不加密

② Payload(载荷)

  • 存用户信息:_idusernameroleexp...
  • 公开、不加密
  • ⚠ 不能放密码!

③ Signature(签名)

  • Header + Payload + 密钥 加密生成
  • 防篡改
  • 后端靠它验证 token 是否有效

JSON Web Tokens - jwt.iohttps://www.jwt.io/

3. JWT 编码 / 解码

编码(后端生成 token)

javascript 复制代码
const token = jwt.sign(user, 'abc123', { expiresIn: '3000h' })

→ 把用户信息变成一段 token 字符串。

解码(后端验证 + 解析)

javascript 复制代码
expressjwt({ secret: "abc123", algorithms: ['HS256'] })

→ 自动解析出用户信息 → 放到**req.auth(鉴权需用到)**

任何人都能解码看内容,但只有密钥能生成合法签名

user.js中login接口生成jwt凭证

javascript 复制代码
        /*
 制作JWT不可篡改凭证
   */
        const token = jwt.sign(
          user,//用户信息对象
          'abc123',//密钥
          { expiresIn: '3000h' } //有效期
        );
        user.token = token;//把token字段加到user对象中
        return res.json({
          code: 2000,
          msg: '登录成功',
          data: user
        });

app.js中的JWT 身份验证 + 全局异常统一处理中间件**:注意全局异常统一处理中间件要写在最后面,否则无法捕获异常。全局错误处理中间件,永远放在所有中间件的最后一个!**

javascript 复制代码
//jwt验证
app.use(
 expressjwt({
    secret: "abc123",
    algorithms: ['HS256'] // 指定签名算法
  }).unless({
    path: ["/login", 
      "/register"//restful风格的网址不是唯一的,要配合method一起明确
      // {url:"/api/v1/users",methods:['POST']},
      // {url:"/api/v1/reports/favcount",methods:['GET']},
    ] // 指定不需要验证的路由 登录和注册接口不需要验证
  })
);

//统一处理异常的中间件
app.use((err, req, res, next) => {
  console.log("err的内容",err)
  if (err.name === 'UnauthorizedError') {
     let message = '无效的令牌';
     console.log("err.inner",err.inner.message)
    // 检查内部错误信息(可选)
    if (err.inner && err.inner.message === 'jwt expired') {
      message = '令牌已过期';
    } else if (err.inner && err.inner.message === 'invalid signature') {
      message = '令牌签名无效';
    }
    // JWT 验证失败
    return res.status(401).json({ code: 4001, msg: message,data:null });
  } else {
    // 其他错误
    return res.status(500).json({ code: 5000, msg: '服务器内部错误:'+err.message,data:null });
  }
});

4. JWT 核心:token 和 req.auth._id

① token = 身份凭证(进门卡)

  • 前端存在 localStorage / sessionStorage

  • 请求时放在请求头:

    复制代码
    Authorization: Bearer token
  • 作用:让后端知道你是登录用户

② req.auth._id = 当前登录用户 ID(钥匙)

  • JWT 验证通过后自动挂载(只在后端可见,前端拿不到)
  • 来源:token 里的 payload
  • 作用:权限判断、数据归属

前端传来的 user._id 不可信,涉及权限与数据归属的操作,必须使用后端从 JWT 解析出的可信用户信息

5.初学踩的坑

初学 JWT 时容易踩坑:误以为用户登录后获取 token,请求拦截器正常携带 token 并通过后端验证就足够安全。但实际上,token 仅用于身份校验,并不直接控制操作权限。如果后端直接信任前端传入的用户 ID,很容易出现被他人冒充身份、越权操作数据的安全问题。

我在 Postman 中使用张三的账号登录获取 token,然后在李书记的发布意见接口中,将请求头的 token 替换为张三的,并在请求体里把用户信息改成李书记的,最终成功发送了请求。可见确实有越权操作风险

相关推荐
这儿有一堆花12 分钟前
深入解析 Video.js:现代 Web 视频播放的工程实践
前端·javascript·音视频
烤麻辣烫27 分钟前
JS基础
开发语言·前端·javascript·学习
IT_陈寒1 小时前
Vue的响应式把我坑惨了,原来问题出在这
前端·人工智能·后端
2603_953527991 小时前
WordPress Finale Lite 插件高危漏洞检测与利用工具 (CVE-2024-30485)
前端·python·安全·web3·xss
2601_949818091 小时前
头歌答案--爬虫实战
java·前端·爬虫
猫猫不是喵喵.2 小时前
layui表单项次大数据量导入并提交
前端·javascript·layui
张小潇2 小时前
AOSP15 WMS/AMS系统开发 - 窗口层级源码分析
android·前端
whuhewei3 小时前
HTTP1/2/3演变
前端·计算机网络
腹黑天蝎座3 小时前
从零实现一个前端监控系统:性能、错误与用户行为全方位监控
前端·监控
Hooray3 小时前
为了在 Vue 项目里用上想要的 React 组件,我写了这个 skill
前端·ai编程