nodejs的jwt实现

JWT

JSON Web Token(JSON Web令牌)

是一个开放标准(rfc7519),它定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任,因为它是数字签名的。jwt可以使用秘密〈使用HNAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

通过JSON形式作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。

JWT作用:
授权:一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。它的开销很小并且可以在不同的域中使用。如:单点登录。
信息交换:在各方之间安全地传输信息。JWT可进行签名(如使用公钥/私钥对),因此可确保发件人。由于签名是使用标头和有效负载计算的,因此还可验证内容是否被篡改。

JWT结构
就是令牌token,是一个String字符串,由3部分组成,中间用点隔开

令牌组成:

标头(Header)
有效载荷(Payload)
签名(Signature)
token格式:head.payload.singurater 如:xxxxx.yyyy.zzzz

案例

以下做一个简单的token签名,前端使用vue,服务器使用nodejs

功能实现,两个页面,一个登录页一个列表页,登录后返回加密token,访问列表页时需要token校验,如果校验不通过返回登录页,通过展示列表页

nodejs实现

app.js

复制代码
const express = require("express");
const app = express();
const bosyParser = require("body-parser");
const jwt = require("jsonwebtoken"); //加载包
app.use(bosyParser.json()); //解析json数据
//跨域
app.use(function (req, res, next) {
  //设置允许跨域的域名,*代表允许任意域名跨域
  res.header("Access-Control-Allow-Origin", "*");
  //  例如 允许百度跨域, 把上面这行的*替换为 https://baidu.com
  //允许的header类型
  res.header("Access-Control-Allow-Headers", "content-type");
  //跨域允许的请求方式
  res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
  if (req.method.toLowerCase() == "options") {
    res.sendStatus(200); //让options预验证尝试请求快速结束
  }
  next();
});

const user = { name: "zhangsan", password: "123456" }; //储存账号,模拟数据库
const theKey = "mykey";//定义密匙

//登录 app.post(
"/login", (req, res) => { if (JSON.stringify(user) === JSON.stringify(req.body)) { let token = jwt.sign(user.name, theKey);//生成token //账号密码正确 res.json({ code: 0, token, data: user }); } else { res.json({ code: 1, data: "账号或密码错误" }); } }); //中间件,校验token let autoCheck = (req, res, next) => { const token = req.headers.authorization && req.headers.authorization.split(" ")[1]; if (token) { req.token = token; next(); } else { res.json("token失效"); } };

//获取列表数据 app.get(
"/list", autoCheck, (req, res) => { const token = req.token; jwt.verify(token, theKey, (err, data) => { //data为解码之后的数据,即name if (!err) { res.json({ code: 0, data }); } else { res.json({ code: 1, data: "token签名错误" }); } }); }); app.listen(4000, () => { console.log("4000端口启动了"); });
复制代码

axios添加拦截,方便操作

复制代码
import axios from "axios";

//添加请求拦截,设置authorization
axios.interceptors.request.use(
  (config) => {
    const token = sessionStorage.getItem("token");
    if (token) {
    //每次请求尝试携带token
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (err) => {
    return Promise.reject(err);
  }
);
//添加响应拦截
axios.interceptors.response.use((res) => {
  if (res.data.code === 0) {
    //响应数据减少一层
    return Promise.resolve(res.data);
  } else {
    return Promise.reject("请求失败");
  }
});

export default axios;
复制代码

两个页面

login.vue

复制代码
 submit() {
      this.$axios.post('/api/login', this.user).then(
        (res) => {
          if (res.code === 0) {
            const { data, token } = res
            token && sessionStorage.setItem('token', token)//保存token
            data && this.$router.push('/list')
          }
        },
        (err) => {
          console.log(err)
        }
      )
    }
复制代码

此处提交url:/api/login使用了代理

 

list.vue

复制代码
 mounted() {
    this.$axios.get('/api/list').then(
      (res) => {
        if (res.code === 0) {
          this.user.name = res.data
        }
      },
      (err) => {
        console.log(err)
        this.$router.push('/login')
      }
    )
  }
复制代码

token在axios中设置了,此次不需要携带token

 

一个简单的登录验证token就实现了。

posted @   lijun12138  阅读(717)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示