当前位置: 首页 > news >正文

Nginx auth_request详解

网上看到多篇先关文章,觉得很不错,这里合并记录一下,仅供学习参考。

模块

nginx-auth-request-module

        该模块是nginx一个安装模块,使用配置都比较简单,只要作用是实现权限控制拦截作用。默认高版本nginx(比如1.12)已经默认安装该模块,下面介绍下使用该模块实现多个站点之间的统一权限控制。

例子1

        这里用一个例子来说明下,如下例子是包含site1(对应web1)、site2(对应web2)、auth(20.131:7001)在内的三个应用项目,auth项目主要做权限拦截,比如jwt校验等,site1、site2分别为两个受保护的资源站点,只有auth授权通过后才能访问该站点。

实现上述要求nginx配置详情如下(nginx地址为20.198):

upstream web1 {server 192.168.20.131:3000;
}upstream web2 {server 192.168.20.131:3001;
}
server {listen       80;server_name  localhost;#charset koi8-r;#access_log  /var/log/nginx/host.access.log  main;location / {root   /usr/share/nginx/html;index  index.html index.htm;}location /api/web1 {auth_request /auth;error_page 401 = @error401;auth_request_set $user $upstream_http_x_forwarded_user;proxy_set_header X-Forwarded-User $user;proxy_pass http://web1;}location /api/web2 {auth_request /auth;error_page 401 = @error401;auth_request_set $user $upstream_http_x_forwarded_user;proxy_set_header X-Forwarded-User $user;proxy_pass http://web2;}location /auth {internal;proxy_set_header Host $host;proxy_pass_request_body off;proxy_set_header Content-Length "";proxy_pass http://192.168.20.131:7001/auth;}location @error401 {add_header Set-Cookie "NSREDIRECT=$scheme://$http_host$request_uri;Path=/";return 302 http://192.168.20.131:7001/login;}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   /usr/share/nginx/html;}
}

        配置好之后,要明白一点,那就是nginx-auth-request-module模块基本使用原理就是:

1、auth_request对应的路由返回401 or 403时,会拦截请求直接nginx返回前台401 or 403信息;

2、auth_request对应的路由返回2xx状态码时,不会拦截请求,而是构建一个subrequest请求再去请求真实受保护资源的接口;

        所以,基于此,auth模块只需要校验然后返回相应的状态码即可实现权限拦截操作,简单测试如下:

auth代码:

// 授权认证接口async auth() {console.log(Date.now());this.ctx.status = 200;}// 失败后的登录页面async login() {console.log('失败了........');this.ctx.body = {msg: '授权失败',code: 10001}}

        这里的auth授权接口我们直接返回200,login是上述auth项目下配置的路由,用于授权失败后302至登录页面用的。

        site1和site2代码相同,只罗列一个如下:

/* /api/web1/users,如果是web2则为/api/web2/users */
router.all('/', function(req, res, next) {res.send('respond with a resource from web1');
});

这里只是简单渲染输出一个字符串而已,测试如下:

浏览器访问:http://192.168.20.198/api/web1/users,输出:

改变auth接口如下:

// 授权认证接口async auth() {console.log(Date.now());this.ctx.status = 401;}// 失败后的登录页面async login() {console.log('失败了........');this.ctx.body = {msg: '授权失败',code: 10001}}

这里将状态码改为了401,再次访问:http://192.168.20.198/api/web1/users,输出:

        这里可以看到,浏览器直接进行了302跳转,因为鉴权失败,直接重定向到登录页面了。

        以上就是关于nginx-auth-request-module模块的基本操作及配置,多个项目下部署统一的权限接口时还是相当有用的。

例子2

        首先,确保Nginx已经安装并启用了auth_request模块。然后,编辑Nginx配置文件(通常是nginx.conf或某个虚拟主机配置文件)。

通过–with-http_auth_request_module添加auth_request模块

http {
  # 定义认证服务的逻辑
  server {
    listen 127.0.0.1:8080;
    location /auth {
      # 此处为简单示例,实际应用中应调用外部认证服务
      if ($http_authorization = "Basic dXNlcm5hbWU6cGFzc3dvcmQ=") {  # 假设认证使用Basic Auth
        return 200;
      }
      return 401;
    }
  }

  server {
    listen 80;
    server_name example.com;

    location / {
      # 使用 auth_request 调用认证服务
      auth_request /auth;

      # 处理认证服务的响应结果
      error_page 401 = @error401;
      error_page 403 = @error403;

      # 正常处理请求
      proxy_pass http://backend;
    }

    # 定义认证失败时的处理逻辑
    location @error401 {
      return 401 "Unauthorized";
    }

    location @error403 {
      return 403 "Forbidden";
    }

    # 认证服务的代理设置
    location /auth {
      proxy_pass http://127.0.0.1:8080/auth;
      proxy_pass_request_body off; # 不代理请求体到认证服务
      proxy_set_header Content-Length "";
      proxy_set_header X-Original-URI $request_uri;
    }
  }
}
 

配置说明

定义认证服务:

server {
  listen 127.0.0.1:8080;
  location /auth {
    if ($http_authorization = "Basic dXNlcm5hbWU6cGFzc3dvcmQ=") {
      return 200;
    }
    return 401;
  }
}

        这个server块模拟了一个简单的认证服务,它监听127.0.0.1:8080,根据请求头Authorization判断用户是否经过认证。在实际应用中,这个应该是一个调用外部服务的代理配置。

主站点配置:

server {
  listen 80;
  server_name example.com;

  location / {
    auth_request /auth;
    error_page 401 = @error401;
    error_page 403 = @error403;
    proxy_pass http://backend;
  }

  location @error401 {
    return 401 "Unauthorized";
  }

  location @error403 {
    return 403 "Forbidden";
  }

  location /auth {
    proxy_pass http://127.0.0.1:8080/auth;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
  }
}

  • auth_request /auth;:该指令告诉Nginx,在处理用户请求前,先将请求发送到/auth进行认证。
  • error_page 401 = @error401;和error_page 403 = @error403;:定义认证失败时的处理逻辑,将401或403错误重定向到相应的处理块。
  • proxy_pass http://backend;:成功认证后,将请求代理到后端服务器。

认证失败处理:

location @error401 {
  return 401 "Unauthorized";
}

location @error403 {
  return 403 "Forbidden";
}

认证失败时,根据实际情况返回401或403状态码,并附带相应的错误信息。

测试与验证

        启动Nginx,尝试访问http://example.com,并使用不同的Authorization头部测试认证行为。如果头部包含正确的用户名和密码(在本例中为"Basic dXNlcm5hbWU6cGFzc3dvcmQ="),请求应被允许访问后端资源,否则返回相应的错误状态码。

例子3

upstream web1 {
    server 192.168.20.131:3000;
}

upstream web2 {
    server 192.168.20.131:3001;
}

location ^~ /session/ {

        charset  utf-8;
        auth_request /session-backend-info/;
        auth_request_set $backend $upstream_http_backend;

        proxy_set_header Forwarded $remote_addr;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Port  $remote_port;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_pass $backend/$request_uri;

    }

$backend为web1、web2 upstream

相关文章:

Nginx auth_request详解

网上看到多篇先关文章,觉得很不错,这里合并记录一下,仅供学习参考。 模块 nginx-auth-request-module 该模块是nginx一个安装模块,使用配置都比较简单,只要作用是实现权限控制拦截作用。默认高版本nginx(比…...

基于Java Springboot个人财务APP且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 微信…...

vue3图片报错转换为空白不显示的方法

vue3图片报错转换为空白不显示的方法 直接上代码&#xff1a; <el-table-column label"领料人" align"center"><template #default"scope"><el-imagev-if"scope.row.receiver":src"scope.row.receiver"style…...

mysq之快速批量的插入生成数据

mysq之快速批量的插入生成数据 1.insert inot select2.存储过程3.借助工具 在日常测试工作时&#xff0c;有时候需要某张表有大量的数据&#xff0c;如&#xff1a;需要有几百个系统中的用户账号等情况&#xff1b;因此&#xff0c;记录整理&#xff0c;如何快速的在表中插入生…...

浅谈C#库之DevExpress

一、DevExpress库介绍 DevExpress是一个功能强大、界面美观的UI组件库&#xff0c;广泛应用于桌面应用程序和Web应用程序的开发中。它提供了丰富的控件和工具&#xff0c;帮助开发人员快速构建现代化的用户界面。DevExpress控件库以其功能丰富、应用简便、界面华丽以及方便定制…...

聊聊Flink:这次把Flink的触发器(Trigger)、移除器(Evictor)讲透

一、触发器(Trigger) Trigger 决定了一个窗口&#xff08;由 window assigner 定义&#xff09;何时可以被 window function 处理。 每个 WindowAssigner 都有一个默认的 Trigger。 如果默认 trigger 无法满足你的需要&#xff0c;你可以在 trigger(…) 调用中指定自定义的 tr…...

一款支持80+语言,包括:拉丁文、中文、阿拉伯文、梵文等开源OCR库

大家好&#xff0c;今天给大家分享一个基于PyTorch的OCR库EasyOCR&#xff0c;它允许开发者通过简单的API调用来读取图片中的文本&#xff0c;无需复杂的模型训练过程。 项目介绍 EasyOCR 是一个基于Python的开源项目&#xff0c;它提供了一个简单易用的光学字符识别&#xff…...

Flink四大基石之CheckPoint(检查点) 的使用详解

目录 一、Checkpoint 剖析 State 与 Checkpoint 概念区分 设置 Checkpoint 实战 执行代码所需的服务与遇到的问题 二、重启策略解读 重启策略意义 代码示例与效果展示 三、SavePoint 与 Checkpoint 异同 操作步骤详解 四、总结 在大数据流式处理领域&#xff0c;Ap…...

JVM 常见面试题及解析(2024)

目录 一、JVM 基础概念 二、JVM 内存结构 三、类加载机制 四、垃圾回收机制 五、性能调优 六、实战问题 七、JVM 与其他技术结合 八、JVM 内部机制深化 九、JVM 相关概念拓展 十、故障排查与异常处理 一、JVM 基础概念 1、什么是 JVM&#xff1f;它的主要作用是…...

Python 调用 Umi-OCR API 批量识别图片/PDF文档数据

目录 一、需求分析 二、方案设计&#xff08;概要/详细&#xff09; 三、技术选型 四、OCR 测试 Demo 五、批量文件识别完整代码实现 六、总结 一、需求分析 市场部同事进行采购或给客户报价时&#xff0c;往往基于过往采购合同数据&#xff0c;给出现在采购或报价的金额…...

K8S资源之secret资源

secret资源介绍 secret用于敏感数据存储&#xff0c;底层基于base64编码&#xff0c;数据存储在etcd数据库中 应用场景举例&#xff1a; 数据库的用户名&#xff0c;密码&#xff0c;tls的证书ssh等服务的相关证书 secret的基础管理 1 在命令行响应式创建 1.响应式创建 …...

QT:信号和槽01

QT中什么是信号和槽 概念解释 在 Qt 中&#xff0c;信号&#xff08;Signals&#xff09;和槽&#xff08;Slots&#xff09;是一种用于对象间通信的机制。信号是对象发出的事件通知&#xff0c;而槽是接收并处理这些通知的函数。 例如&#xff0c;当用户点击一个按钮时&#…...

针对Qwen-Agent框架的Function Call及ReAct的源码阅读与解析:Agent基类篇

文章目录 Agent继承链Agent类总体架构初始化方法`__init__` 方法:`_init_tool` 方法:对话生成方法`_call_llm` 方法:工具调用方法`_call_tool` 方法:`_detect_tool` 方法:整体执行方法`run` 方法:`_run` 方法:`run_nonstream` 方法总结回顾本文在 基于Qwen-Agent框架的Functio…...

XML 查看器:深入理解与高效使用

XML 查看器:深入理解与高效使用 XML(可扩展标记语言)是一种用于存储和传输数据的标记语言。它通过使用标签来定义数据结构,使得数据既易于人类阅读,也易于机器解析。在本文中,我们将探讨 XML 查看器的功能、重要性以及如何高效使用它们。 什么是 XML 查看器? XML 查看…...

《Vue零基础入门教程》第十五课:样式绑定

往期内容 《Vue零基础入门教程》第六课&#xff1a;基本选项 《Vue零基础入门教程》第八课&#xff1a;模板语法 《Vue零基础入门教程》第九课&#xff1a;插值语法细节 《Vue零基础入门教程》第十课&#xff1a;属性绑定指令 《Vue零基础入门教程》第十一课&#xff1a;事…...

以AI算力助推转型升级,暴雨亮相CCF中国存储大会

2024年11月29日-12月1日&#xff0c;CCF中国存储大会&#xff08;CCF ChinaStorage 2024&#xff09;在广州市长隆国际会展中心召开。本次会议以“存力、算力、智力”为主题&#xff0c;由中国计算机学会&#xff08;CCF&#xff09;主办&#xff0c;中山大学计算机学院、CCF信…...

【VMware】Ubuntu 虚拟机硬盘扩容教程(Ubuntu 22.04)

引言 想装个 Anaconda&#xff0c;发现 Ubuntu 硬盘空间不足。 步骤 虚拟机关机 编辑虚拟机设置 扩展硬盘容量 虚拟机开机 安装 gparted sudo apt install gparted启动 gparted sudo gparted右键sda3&#xff0c;调整分区大小 新大小拉满 应用全部操作 调整完成...

3D Bounce Ball Game 有什么技巧吗?

关于3D Bounce Ball Game&#xff08;3D弹球游戏&#xff09;的开发&#xff0c;以下是一些具体的技巧和实践建议&#xff1a; 1. 物理引擎的使用&#xff1a; 在Unity中&#xff0c;使用Rigidbody组件来为游戏对象添加物理属性&#xff0c;这样可以让物体受到重力影响并发…...

【SQL】实战--组合两个表

题目描述 表: Person ---------------------- | 列名 | 类型 | ---------------------- | PersonId | int | | FirstName | varchar | | LastName | varchar | ---------------------- personId 是该表的主键&#xff08;具有唯一值的列&#xff09;…...

Spring基于注解实现 AOP 切面功能

前言 在Spring AOP&#xff08;Aspect-Oriented Programming&#xff09;中&#xff0c;动态代理是常用的技术之一&#xff0c;用于在运行时动态地为目标对象生成代理对象&#xff0c; 并拦截其方法调用。Spring AOP 默认使用两种类型的动态代理机制&#xff1a;JDK 动态代理和…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...