在next.js的13.2.1版本中使用中间件,实现禁止特定ip访问网址所有页面

在实现实现禁止特定ip访问网址所有页面时,有两种方式,一种是针对单个页面,另一种是针对整个网站

在pages/api中创建文件使用,针对单个页面,也可以应用于所有页面

之前是在pages/api下创建的中间件去实现的,但是使用pages/api中的中间件需要手动调用,也就是说如果全部页面都需要使用的话,那么就要在所有页面中去调用,页面刷新会重新加载getIp文件,也就是说会重置cachedData、cacheTime这些变量,不刷新的话就不会每次只会执行handler函数内部的代码,所以可以使用缓存,每次刷新后,就会重新请求一次,不刷新且满足条件的,就会使用缓存。
pages/api/getIp.js

// ipBlockMiddleware.js// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from 'axios'
let cachedData = null;
let cacheTime = null;
/**
* 获取地区信息
* @param {*} req
* @param {*} res
*/
export default async function handler(req, res, next) {const blockedIPs = ['82.116.192.22']; // 被禁止的IP列表:塞浦路斯// 设置缓存有效期为10分钟const TEN_MINUTES = 10 * 60 * 1000;try {// 检查缓存是否有效if (cachedData && cacheTime && Date.now() - cacheTime < TEN_MINUTES) {} else {// 获取ip信息const response = await axios.get('https://api.ipdatacloud.com/v2/query?key=xxx',{ timeout: 5000 })// 更新缓存cachedData = response.data.data.locationcacheTime = Date.now();}if (blockedIPs.includes(cachedData?.ip)) {res.statusCode = 403res.end('Forbidden');} else {next && next();}} catch (error) {console.log(error);}
}

如果要在首页中使用getIp,就需要在index.js页面中的getServerSideProps使用,如果对网站所有页面都需要使用的话,那工程就有点大。所有这种方法只适用于单个页面的时候。
注意:** getServerSideProps 只能在组件中使用,像_app.js是不能使用的**


import getIp from './api/getIp'
export async function getServerSideProps({ req, res, locale }) {await getIp(req, res, () => {console.log(1111111);}); // 使用中间件return {props: {},};
}
应用于所有页面

在_app.js文件中,使用getInitialProps方法可行,这是个老版本的方法,这样当页面切换就会触发getInitialProps


import getIp from '@/pages/api/getIp'
const App = ({ Component, pageProps }) => {
.....
}
App.getInitialProps = async (context) => {console.log('_app.js');await getIp(context.ctx.req, context.ctx.res)return {}
}

在src目录下创建一个middleware.js文件实现全局使用中间件

middleware
首先要在src目录下创建一个middleware.js文件
在middleware中不能使用axios发送请求,需要使用fetch发送请求,fetch请求会返回一个方法p.json()是一个promise,返回的才是数据
在middleware中是全局使用的,编写代码后不用手动引用,任何资源请求都会触发middleware里的代码,所以会很频繁的触发,如果里面有接口请求的话,而pages/api中的则需要到具体的页面中的getServerSideProps去手动调用
middleware.js

import { NextResponse, NextRequest } from 'next/server'
// import axios from 'axios'
export const middleware = async (request, response) => {const blockedIPs = ['127.0.0.1', '192.168.0.1', '113.76.109.114', '183.9.77.26', '113.76.109.131']; // 被禁止的IP列表try {const p = await fetch('https://api.ipdatacloud.com/v2/query?key=ccc')const d = await p.json()if (blockedIPs.includes(d.data.location.ip)) {// 符合条件则禁止页面访问,通过NextResponse.json在页面显示Forbidden字样return NextResponse.json('Forbidden', {status: 403})} else {// 正常就不做处理,直接下一步return NextResponse.next()}} catch (error) {console.log(error);}
};

注意:

  1. 不能在middleware函数上使用async/await 否则npm run build 的时候会报错如下错误:
    ./node_modules/@babel/runtime/regenerator/index.js
    Dynamic Code Evaluation (e. g. ‘eval’, ‘new Function’, ‘WebAssembly.compile’) not allowed in Edge Runtime
    Learn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation
  2. middleware中不能使用axios发送请求,需要使用fetch发送请求

上述代码打包会报错,以下代码才是正确的方式,不在middleware使用async/await,可以通过在middleware内部生成一个函数使用async/await:

import { NextResponse, NextRequest } from 'next/server'
// import axios from 'axios'
console.log(1111);
export const middleware = (request, response) => {// 这种方法不行,即使符合被禁用的条件还是能访问,因为没有在同步代码中手动return一个结果// const blockedIPs = ['CY']; // 被禁止的IP列表:塞浦路斯// try {//   // 这里不能使用axios发起请求,所以使用fetch//   fetch('https://api.ipdatacloud.com/v2/query?key=ccccc').then(res => {//     return res.json()//   }).then(res => {//     console.log('kkkkkkkk');//       const country_code = res.data?.location?.country_code// if (!blockedIPs.includes(country_code)) {//   console.log(6666666);//     return NextResponse.json('Forbidden', {//           status: 403//         })//   } else {//     return NextResponse.next()//   }//   })// } catch (error) {//   console.log(error);// }// 这种方法可以,因为在最后面手动return了一个值,这个值是fn异步函数的返回结果const fn = async () => {const blockedIPs = ['CY']; // 被禁止的IP列表try {const p = await fetch('https://api.ipdatacloud.com/v2/query?key=cccc')const d = await p.json()if (blockedIPs.includes(d.data.location.country_code)) {console.log(2222);// 符合条件则禁止页面访问,通过NextResponse.json在页面显示Forbidden字样return NextResponse.json('Forbidden', {status: 403})} else {// 正常就不做处理,直接下一步return NextResponse.next()}} catch (error) {console.log(error);}}// 必须在同步代码中返回,否则即使异步结果返回后符合禁止访问条件,还是能访问return fn()
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/659271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot集成RocketMQ

本文目的是&#xff1a;教会你使用Spring Boot集成RocketMQ。 pom.xml文件引入rocketMQ依赖 <!-- rocketmq 依赖--><dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId>&…

XCTF:warmup[WriteUP]

CtrlU查看页面源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible&q…

嵌入式学习第十四天!(结构体、共用体、枚举、位运算)

1. 结构体&#xff1a; 1. 结构体类型定义&#xff1a; 嵌入式学习第十三天&#xff01;&#xff08;const指针、函数指针和指针函数、构造数据类型&#xff09;-CSDN博客 2. 结构体变量的定义&#xff1a; 嵌入式学习第十三天&#xff01;&#xff08;const指针、函数指针和…

KAFKA鉴权设计以及相关探讨

文章目录 1. kafka的鉴权设计2. kafka鉴权应用范围3. kafka鉴权的常用方法3.1 SASL/GSSAPI3.2 SASL/PLAIN3.2.1 配置jaas3.2.2 配置服务启动参数3.2.3 配置server.perperties 4. 参考文档 鉴权&#xff0c;分别由鉴和权组成 鉴&#xff1a; 表示身份认证&#xff0c;认证相关用…

深度学习侧信道攻击的集成方法

深度学习侧信道攻击的集成方法 深度学习侧信道攻击的集成方法项目背景与意义摘要项目链接作者数据集CHES CTF 数据集ASCAD FIXED KEY 数据集ASCAD RANDOM KEY 数据集 代码代码执行神经网络 深度学习侧信道攻击的集成方法 项目背景与意义 在TCHES2020&#xff08;第4期&#x…

安卓线性布局LinearLayout

<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"android:…

如何用MapTalks IDE来发布网站?

简介 MapTalks IDE 全称 MapTalks集成设计环境&#xff08;Integrated Design Environment&#xff09;&#xff0c;是由MapTalks技术团队开发的新一代web地图设计软件。 通过MapTalks IDE&#xff0c;您可以自由的创建二维和三维地图&#xff0c;在其中载入或创建地理数据&a…

什么是okhttp?

OkHttp简介&#xff1a; OkHttp 是一个开源的、高效的 HTTP 客户端库&#xff0c;由 Square 公司开发和维护。它为 Android 和 Java 应用程序提供了简单、强大、灵活的 HTTP 请求和响应的处理方式。OkHttp 的设计目标是使网络请求变得更加简单、快速、高效&#xff0c;并且支持…

【数据结构与算法】之哈希表系列-20240130

这里写目录标题 一、383. 赎金信二、387. 字符串中的第一个唯一字符三、389. 找不同四、409. 最长回文串五、448. 找到所有数组中消失的数字六、594. 最长和谐子序列 一、383. 赎金信 简单 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不…

【Midjourney】新手指南:命令

1./ask 向Midjourney提问&#xff0c;不过问题和回答都是英文的&#xff0c;例如&#xff1a; 2./blend 将两张图片合并为一张 ​ 3./describe 上传一张图片&#xff0c;Midjourney会生成四组该图片相关的关键词&#xff0c;可以使用这些关键词再生成图片。 ​ 4./turbo …

力扣 55.跳跃游戏

思路&#xff1a; 从后往前遍历&#xff0c;遇到元素为0时&#xff0c;记录对应的下标位置&#xff0c;再向前遍历元素&#xff0c;看最大的跳跃步数能否跳过0的位置&#xff0c;不能则继续往前遍历 代码&#xff1a; class Solution { public:bool canJump(vector<int>…

毕业设计过程学习

传统的目标检测算法主要通过人工设计与纹理、颜色和形状相关的特征来进行目标区域特征的提取。随着深度学习和人工智能技术的飞速发展&#xff0c;目标检测技术也取得了很大的成就。早期基于深度学习的目标检测算法的研究方向仍然是将目标定位任务和图像分类任务分离开来的&…

uni-app在hbuilderx打开微信开发工具运行

一、运行设置配置微信开发者工具路径 运行-运行到小程序模拟器-运行设置 配置微信开发工具的安装路径&#xff08;可浏览文件位置选择&#xff09;&#xff1b;web服务器端口号在第二步骤获得&#xff1b; 二、打开微信开发者工具设置-安全设置 打开服务端口开关&#xff0…

使用ffmpeg madiamtx制作一个rtsp源

有很多人在跑rtsp解码的demo的时候, 苦于找不到一个可以拉流的源, 这里说一个简单的方法. 使用mediamtx, 加ffmpeg加mp4文件方式, 模拟一个rtsp的源. 基本架构就是这样. 在PC上, 这里说的PC可以是远程的服务器, 也可以是你的开发用的windows, 都行. 把mediamtx, 在pc上跑起来 …

书写触感细腻的电容触控笔,透明造型超好看,西圣Pencil2上手

iPad在配上手写笔之后&#xff0c;才能才能充分发挥优势&#xff0c;实现除看视频之外的更多功能。很多人入手iPad的初衷都是工作或者学习&#xff0c;如果只拿来观剧或玩游戏就太浪费了。当然了&#xff0c;现实情况下&#xff0c;Apple Pencil高昂的定价也是很多人望而却步的…

【2024-01-20】 瑞幸咖啡小程序-blackbox

需要联系主页V 瑞幸咖啡小程序 登入需要过同盾滑块下单需要balckbox参数 测试 下单 过滑块 登入发短信 加密参数

理解React中的setState()方法

在React中&#xff0c;setState()方法是一个非常重要的概念&#xff0c;它用于更新组件的状态并触发重新渲染。本文将探讨setState()的使用方法、工作原理以及一些基本的用法。 setState()方法简介 setState()是React组件中用于更新状态的方法之一。它接受一个对象或一个函数作…

第九节HarmonyOS 常用基础组件20-Divider

1、描述 提供分割器组件&#xff0c;分割不同内容块或内容元素。 2、接口 Divider() 3、属性 名称 参数类型 描述 vertical boolean 使用水平分割线还是垂直分割线。 false&#xff1a;水平分割线 true&#xff1a;垂直分割线 color ResourceColor 分割线颜色 默认…

【揭秘】诱骗28V竟如此简单--HUSB238A-EVB-V2.0 使用指南

随着USB TYPE-C的流行&#xff0c;越来越多的桶形连接器正在转换成USB-C连接器&#xff0c;越来越多的电子产品从传统的USB接口升级为TYPE-C接口&#xff0c;并实现PD快充。大一统的充电接口, 充电器接口全兼容&#xff0c;给消费者带来极大的便利。当下&#xff0c;筋膜枪、无…

Linux下Docker Compose安装指南

前言 在Linux的领域里&#xff0c;掌握Docker Compose的安装是迈向容器化技术的第一步。本文将简洁明了地引导您完成安装过程&#xff0c;帮助您更轻松地驾驭容器化技术。 1. 确保系统环境 确保您的系统已经安装了Docker。如果尚未安装&#xff0c;请参考这里进行安装。 2.…