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 替换为张三的,并在请求体里把用户信息改成李书记的,最终成功发送了请求。可见确实有越权操作风险

相关推荐
铭毅天下2 小时前
EasySearch Rules 规则语法速查手册
开发语言·前端·javascript·ecmascript
GISer_Jing2 小时前
AI Agent操作系统架构师:Harness Engineer解析
前端·人工智能·ai·aigc
英俊潇洒美少年2 小时前
css中专门用来提升渲染性能、减少重排重绘的属性
前端·css
天若有情6732 小时前
前端HTML精讲01:别再乱 div 一把抓,吃透语义化标签才是进阶第一步
前端·html
Highcharts.js2 小时前
React 开发者的图表库生态:Highcharts React
前端·react.js·前端框架
阿部多瑞 ABU2 小时前
文明文化悖论
前端·人工智能·ai写作
流光墨佰3 小时前
我做了一个专为油猴打造的轻量级 Vue 组件注入库
vue.js
钛态3 小时前
Flutter 三方库 react 泛前端核心范式框架鸿蒙原生层生态级双向超能适配:跨时空重塑响应式单向数据流拓扑与高度精密生命周期树引擎解耦视图渲染控制中枢(适配鸿蒙 HarmonyOS ohos)
前端·flutter·react.js
全栈前端老曹3 小时前
【前端地图】地图开发基础概念——地图服务类型(矢量图、卫星图、地形图)、WGS84 / GCJ-02 / BD09 坐标系、地图 SDK 简介
前端·javascript·地图·wgs84·gcj-02·bd09·地图sdk