JWT 技术的使用

应用场景:访问某些页面,需要用户进行登录,那我们如何知道用户有没有登录呢,这时我们就可以使用jwt技术。用户输入的账号和密码正确的情况下,后端根据用户的唯一id生成一个独一无二的token,并返回给前端,前端把token保存起来,每次发送请求,请求头携带一个token,以表示用户的身份。当然,后端也要进行校验,确保用户的token不是伪造和过期的。

下面举个例子,使用node搭建服务器来详细说明 jwt 的具体用法。

1.用户通过提供身份信息(如账号和密码)进行身份验证

2.服务器验证用户提供的身份信息,如果验证通过,则并生成一个token并返回给客户端

jsx 复制代码
if (req.query["username"] && req.query["password"]) {
      const { password, username } = req.query;
      // 1. 根据用户名查找用户
      const user = await Admin.findOne({ username }).select("+password");
      // 如果用户名没找到
      if (!user) return resp.send({ code: 422, message: "用户不存在!" });
      // 2. 校验密码(比较明文和密文的密码)
      const isTrue = require("bcryptjs").compareSync(password, user.password);
      // 如果密码错误,则抛出错误状态码和错误信息
      if (!isTrue) return resp.send({ code: 422, message: "密码错误!" });
      // 3. 返回token值(利用公钥加密用户的唯一id,得到token值,并且设置了过期时间为2小时)
      const token = jwt.sign({ id: user._id }, app.SECRET, { expiresIn: "2h" });
      // 查找用户信息
      const userInfo = await Admin.find({ username: req.query.username }).sort({
        timeStamp: -1,
      });
      // 成功生成 JWT,将 JWT 返回给客户端
      resp.setHeader("Access-Control-Allow-Origin", "*");
      resp.setHeader("Access-Control-Expose-Headers", "Authorization");
      resp.setHeader("Authorization", `Bearer ${token}`);
      return resp.send({ token, code: 200, userInfo });
    }

3.客户端将 token 保存到本地中

jsx 复制代码
//设置响应拦截器
  instance.interceptors.response.use(
    (res) => {
      if (res.headers.authorization) { 
        const token = res.headers.authorization.split(" ")[1]
        console.log('token',token);
        localStorage.setItem('token',token)
      }
      // 拦截后需要将拦截下来处理成的结果返回
      return res.data;
    },
    (err) => {
      console.log(err);
    }
  );

4.在后续请求中将 token 放在请求的头部,以表示用户的身份

jsx 复制代码
// 请求拦截器
  instance.interceptors.request.use(
    (config) => {
      // 将token拿出来,拼接到请求头上
      const token = localStorage.getItem("token");
      if (token) {
        config.headers.Authorization = `Bearer ${jwt}`;
      }
      //请求成功的函数
      return config;
    },
    (err) => {
      return err;
    }
  );

5.服务器在接收到请求时,验证 token 的有效性,并根据其中的信息进行授权和验证。

jsx 复制代码
// 判断用户token是否合法
  router.get("/verify", async (req, resp) => {
    const { token } = req.query;
    console.log(token);
    **// 如果token是伪造的,则直接抛出异常
    try {
      const obj = jwt.verify(token, app.SECRET);
      console.log(obj);
      // obj.exp 是过期的时间(单位为s)
      if (Date.now() >= obj.exp * 1000) {
        resp.send({ code: 401, message: "无效的JWT令牌" });
      } else { 
        resp.send({ code: 200, message: "success" });
      }
    } catch (error) {
      resp.send({ code: 401, message: "无效的JWT令牌" });
    }
  });
相关推荐
Eiceblue12 分钟前
如何构建一个纯前端 Word 转 Markdown 转换器(React + WebAssembly)
前端·react.js·word
平头哥~25 分钟前
Day 15 | 不改一行 HTML,给页面加上引号、角标和标签
前端·javascript·css·html·css3·学习资料
风骏时光牛马29 分钟前
后端系统性能监控与异常告警管理
前端
Fluxart.ai1 小时前
GPT Image 2 国内怎么用?在 Flux Art 完成图片生成与编辑
前端·javascript·gpt
tanzongbiao2 小时前
Dorado7文件上传 解决HttpServletResponse返回值中文乱码的问题
java·服务器·前端
郑州光合科技余经理5 小时前
本地生活服务系统:成品模块和定制接口怎么划界
java·前端·人工智能·后端·系统架构·php·ai编程
平头哥~9 小时前
Day 07 _ 那条 1px 的线,为什么在手机上忽粗忽细
前端·css·样式·学习资料
小江的记录本10 小时前
【CSS】CSS 动画:transition、animation、transform、CSS3 新特性(附《思维导图》)
前端·css·安全·spring·前端框架·css3·动画
circuitsosk10 小时前
任务规划器的三种范式对比:ReAct、Plan-and-Execute 与 Tree-of-Thought 在真实业务中的取舍
前端·javascript·python·react.js·llm·ai agent
hzxpaipai11 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构