【Express】登录鉴权 JWT

news/2024/7/19 8:47:10 标签: express

JWT(JSON Web Token)是一种用于实现身份验证和授权的开放标准。它是一种基于JSON的安全传输数据的方式,由三部分组成:头部、载荷和签名。

使用jsonwebtoken模块,你可以在Node.js应用程序中轻松生成和验证JWT。以下是jsonwebtoken库的使用步骤:

  1. 安装jsonwebtoken模块:在命令行中运行npm install jsonwebtoken来安装jsonwebtoken模块。

  2. 导入jsonwebtoken模块:在你的Node.js应用程序中,使用require语句导入jsonwebtoken模块。

const jwt = require('jsonwebtoken');
  1. 生成JWT:使用jsonwebtoken的sign方法生成JWT。该方法接受三个参数:载荷(Payload)、密钥和可选的配置对象。载荷是一个包含有关用户/客户端的信息的对象。
const payload = {
  userId: '123456789',
  username: 'example_user'
};

const secretKey = 'your_secret_key';

const token = jwt.sign(payload, secretKey, { expiresIn: '1h' });

上述代码将生成一个JWT,其中包含了userId和username信息,使用了一个密钥进行签名,并设置了过期时间为1小时。生成的JWT将作为一个字符串存储在token变量中。

  1. 验证JWT:使用jsonwebtoken的verify方法验证JWT的有效性。该方法接受三个参数:要验证的JWT、密钥和一个可选的回调函数。
const token = 'your_generated_jwt';

jwt.verify(token, secretKey, (err, decoded) => {
  if (err) {
    // JWT验证失败
    console.log('JWT verification failed.');
  } else {
    // JWT验证成功
    console.log('JWT verified successfully.');
    console.log(decoded); // 解码后的JWT负载
  }
});

上述代码将验证传入的JWT是否有效,并使用提供的密钥进行签名验证。如果JWT有效,verify方法回调函数中的decoded参数将包含解码后的JWT负载信息。如果JWT无效,则会在回调函数中得到一个错误。

以下是 JWT 的一个简单的封装:

//jsonwebtoken 封装

const jsonwebtoken = require("jsonwebtoken")
// 设置密钥
const secret = "anydata"
const JWT = {
	// 生成 token
    generate(value,exprires){
    	// value 数据,expires 过期时间
        return jsonwebtoken.sign(value,secret,{expiresIn:exprires})
    },
    // 校验 token
    verify(token){
    	// 放在 try...catch... 中,防止报错
        try{
            return jsonwebtoken.verify(token,secret)
        }catch(error){
            return false
        }
    }
}

module.exports = JWT
const token = JWT.generate('xx', '10s')
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoieHgiLCJpYXQiOjE2OTc0Mzk3MTEsImV4cCI6MTY5NzQzOTcyMX0.vfcaK_tHfbD-58nqcDRopg516jngqWJhw6zr229zACM
// header.数据.签名
console.log(JWT.verify(token))
// node 中间件校验
app.use((req,res,next)=>{
  // 如果token有效 ,next() 
  // 如果token过期了, 返回401错误
  if(req.url==="/login"){
    next()
    return;
  }
  const token = req.headers["authorization"]?.split(" ")[1]
  if(token){
    var payload = JWT.verify(token)
    // console.log(payload)
    if(payload){
      const newToken = JWT.generate({
        _id:payload._id,
        username:payload.username
      },"1d")
      res.header("Authorization",newToken)
      next()
    }else{
      // errCode 和 errInfo 是 network 的 preview 中返回的数据
      res.status(401).send({errCode:"-1",errInfo:"token过期"})
    }
  }
})

 //生成token
const token = JWT.generate({
    _id: result[0]._id,
    username: result[0].username
}, "1d")

res.header("Authorization", token)
//前端拦截
import axios from 'axios'
// Add a request interceptor
axios.interceptors.request.use(function (config) {
    const token = localStorage.getItem("token")
    config.headers.Authorization = `Bearer ${token}`
    return config;
  }, function (error) {
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    const {authorization } = response.headers
    authorization && localStorage.setItem("token",authorization)
    return response;
  }, function (error) {
    const {status} = error.response
    if(status===401){
    	// 移除本地失效的 token 值,由于过期而失效
        localStorage.removeItem("token")
        window.location.href="/login"
    }
    return Promise.reject(error);
  });

业务逻辑:

  1. 后端下载、导入模块 npm i jsonwebtoken
  2. 封装生成token、验证token方法
  3. 登录接口中将前端提供的字段生成token并放到登录接口响应头中
  4. 前端将token存储(并在每个请求的请求头中加入token,请求拦截添加token,响应拦截存储token)
  5. 后端设置应用级中间件
    5.1. 排除登录接口、路由
    5.2. 获取前端传过来的请求头并判断状态
    5.2.1. 有token:重新设置token并放在响应头传给前端(刷新过期时间)
    5.2.2. 无token:返回401给前端
  6. 前端响应拦截:无401跳转登录页并置空本地token

http://www.niftyadmin.cn/n/5096377.html

相关文章

2、Calcite 源码编译与运行

Calcite 源码编译与运行 一、概述 1)简介 Calcite是一个数据库查询优化器。 2)使用方式 1.将Calcite作为独立的服务,向下对接异构数据源,上层应用则使用Calcite原生的JDBC接口,利用SQL语句进行请求和响应。 2.将…

什么是关系数据库,你知道吗?

什么是关系数据库管理系统 关系数据库管理系统(RDBMS,relational database management system)是基于关系数据模型的数字数据库,由 E. F. Codd 于 1970 年提出。 许多关系数据库都提供使用结构化查询语言 SQL(Struct…

Python 字符串相关函数

str.rstrip([chars]) 删除 string 字符串末尾的指定字符,默认为空白符,包括空格、换行符、回车符、制表符 chars: 指定删除的字符(默认为空白符) 返回删除 string 字符串末尾的指定字符后生成的新字符串 #!/usr/bin/python # …

PTE-精听学习(一)

目录 SST SST每一题都是单独计时 MMA 切换题目的时候,总是会迷茫 deduct 出现关键词之后,才开始精听 没有人管你 ,绝对是要为后方留出更多的时间 ,选多一个错的,要倒扣分 特征 1.paraphrase 2.循序出现 …

.Net Core 6 运行环境手动安装流程

安装.NET Core 6 概述 在开始之前,我们首先需要了解一下整个安装过程的流程。下面的表格将展示安装.NET Core 6的步骤以及每一步需要做的事情。 步骤 动作 说明 1 下载.NET Core 6 SDK 从官方网站下载.NET Core 6 SDK安装包 2 安装.NET Core 6 SDK …

网络工程师知识点6

91、3、IP ABC类私有地址和个数 A类私有地址1个:10.0.0.0/8 B类私有地址16个:172.16.0.0~172.31.0.0/16 C类私有地址256个:192.168.0.0~192.168.255.0/24 92、拥塞管理机制的实现过程分为哪两步? 第一步:将准备从一个…

【Linux】线程的几种退出方法(知识点小记)

线程的几种退出方法: 方法参数介绍头文件功能区别return stutus;status//程序退出的返回值--返回到上一级主调函数 普通线程执行return,只退出当前线程 主函数中执行return,会退出进程,并释放所有线程 exit(int status);status//…

TP5.1 导出excel文件

在 ThinkPHP 5.1 中引入 PHPExcel(现在已被官方弃用,推荐使用 PhpSpreadsheet)时,可以按照以下步骤进行操作: 在 composer.json 文件中添加 PHPExcel(PhpSpreadsheet)的依赖项。找到 require 部…