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

相关推荐
To_OC5 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic6 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy6 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志6 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble7 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯8 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜9 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司9 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g10 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森10 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http