JWT 技术的使用

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

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

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

JWT 技术的使用_第1张图片

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

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 保存到本地中

//设置响应拦截器
  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 放在请求的头部,以表示用户的身份

// 请求拦截器
  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 的有效性,并根据其中的信息进行授权和验证。

// 判断用户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令牌" });
    }
  });

你可能感兴趣的:(状态模式,javascript,前端,node.js)