img标签请求拦截_通过nginx代理拦截请求进行全局访问限制

本文介绍了一种通过nginx代理拦截请求的方法,解决全局访问限制问题,特别是针对img标签请求和Tomcat虚拟目录的权限管理。在详细步骤中,包括了升级nginx、添加ngx_http_accesskey_module模块,以及配置nginx访问key,以此实现未登录用户访问资源的404拦截,而登录用户可以正常访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文介绍了通过nginx代理拦截请求进行全局访问限制,分享给大家,具体如下:

运行环境:Ubantu 14.0

tomcat7

nginx 1.4.6(更新后1.5.6)

项目中经常会用到权限管理,必然的就会存在权限的设定和验证;对于登陆或者模块的权限设定验证,在项目中直接实现;那么问题出现了

1.访问资源文件

2.多项目访问权限

3.tomcat中虚拟目录的访问权限

公司项目中用到文件的上传下载,在线预览等功能;当然用户在使用的时候,我们不可能把用户的上传的文件放在项目中,那么必然会用到

虚拟目录来映射文件的位置,或者说跨域夸项目;如果没有对这些进行一个访问的权限的限制,那么你将可以不需要任何权限就可以访问下载

服务器上的资源(只要路径正确不需要任何权限),下面拿公司项目实际情况说明一下:

比如访问: http://192.168.1.118/filefindPDFfilePath?filePath=root/(A)/上传应用描述.docx 将出现

filefindPDFfilePath?filePath=root/(A)/上传应用描述.docx http 请求会返回 /imgss/(A)/上传应用描述.docx(imgss是tomcat server.xml配置的虚拟目录)

打开浏览器我们直接访问虚拟目录:http://192.168.1.118/imgss/(A)/上传应用描述.docx 将出现不需要任何权限可以预览或者使用工具下载服务器资源

这会导致客户在使用时,在稍有心思的人面前没有任何安全可言

下面说一下如何解决这个问题:

第一种方案:设置tomcat全局过滤器,进行session验证

1.项目中添加过滤器 UserLoginFilter.java(这里就不赘述了)

2.在tomcat 配置文件web.xml添加Filter

注意这里:applicaton/com.rhxy.service.UserLoginFilter 指向项目中的UserLoginFilter过滤器

这里需要说明一下。配置的拦截请求都是tomcat server.xml中配置的虚拟路径

而所有的访问资源的请求都是需要经过这里,所以直接设置虚拟路径即可

启动tomcat 重新部署项目;进行测试。结果如下

未登录情况下

访问:http://192.168.1.118/filefindPDFfilePath?filePath=root/(A)/12.png 打开tomcat 日志进行观察:

观察一下前台:

未登录情况下被成功被过滤掉了

测试直接访问虚拟目录:http://192.168.1.118/imgss/(A)/12.png同样被拦截

然后测试登陆后访问,就出现问题了。请求是被过滤了,但是权限验证合格以后请求返回的status 居然是404

后台日志:

前台:

http://192.168.1.118/filefindPDFfilePath?filePath=root/(A)/12.png

http://192.168.1.118/imgss/(A)/12.png  通过后台观察,请求都是有经过过滤器进行session验证,并且都是验证通过,然而还是出现404,资源在

服务器中是肯定存在的,tomcat 中的虚拟目录设置也没有问题;经过多次测试问题出在tomcat配置文件web.xml配置的过滤器,映射的是项目中的过滤器

那么将过滤器打包成jar 以后,放置在tomcat 中,然后修改web.xml配置文件,修改Filter 中filter-class 为jar包打包的路径,然后测试发现项目无法启动。

在配置Filter 中filter-class 路径时出错;然后经过一系列尝试,最终还是失败,因为时间有限,所以只能放弃这种,但是我相信思路肯定是正确的,因为

听说已经有人实现了,但是没有具体说明,下面开始尝试第二种

第二种方案:通过nginx代理拦截请求,并进行访问限制

1.使用 nginx -V 查看版本几安装的模块,查看是否有ngx_http_accesskey_module模块,没有的话需要为nginx加入ngx_http_accesskey_module模块(附件),因为我的版本是1.4.6上面很多模块都没有,先进行升级

1.1)下载nginx-1.5.6.tar.gz (文件位置在/root下)wget http://nginx.org/download/nginx-1.5.6.tar.gz

1.2)解压nginx-1.5.6.tar.gz文件tar zxvf nginx-1.5.6.tar.gz

1.3)进入ngixn-1.5.6文件夹中cd nginx-1.5.6

1.4)查看nginx原来的配置输出:--prefix=/etc/nginx--conf-path=/etc/ nginx/nginx.conf--error-log-path=/var/log/nginx/error.log --http-client-body-te mp-path=/var/lib/nginx/body--http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log--http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi--http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid--with-http_realip_module --with-http_stub_status_module--with-http_ssl_module

--with-debug--with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6--with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl

--with-mail--with-mail_ssl_module

2.下载ngx_http_accesskey_module模块

2.1)mkdir -p /etc/nginx/third-modules

2.2)cd /etc/nginx/third-modules

2.3)wget ftp://91.193.69.2/distributive/FreeBSD/ports/local-distfiles/osa/nginx-accesskey-2.0.3.tar.gz

2.4)tar -zxvf nginx-accesskey-2.0.3.tar.gz

2.5)修改下nginx-accesskey-2.0.3的config文件:把$HTTP_ACCESSKEY_MODULE修改成ngx_http_accesskey_module

3.返回root下nginx-1.5.6

3.1)执行configure命令,后面跟上原来nginx的配置 并添加ngx_http_accesskey_module./configure --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/etc/nginx/third-modules/nginx-accesskey-2.0.3

在执行configure时得到几个错误:

a.配置 --with-http_xslt_module 时提示 the HTTP XSLT module requires the libxml2/libxslt librariessudo apt-get install libxml2 libxml2-dev libxslt-dev

b.配置 --with-http_image_filter_module 时提示 the HTTP image filter module requires the GD library.sudo apt-get install libgd2-xpm libgd2-xpm-dev

c.配置 --with-http_geoip_module 时提示 the GeoIP module requires the GeoIP library.sudo apt-get install geoip-database libgeoip-dev

d.rewrite需要pcre支持, 错误提示:./configure: error: the HTTP rewrite module requires the PCRE library.apt-get install libpcre3 libpcre3-dev

e.ubuntu error: SSL modules require the OpenSSL library.sudo apt-get install openssl libssl-dev

3.2)再执行第6步的configure命令

3.3)这次没有提示缺少library, 执行make令命编译nginx, 编译好以后objs目录下多出一个nginx文件,这个就是已编辑好的nginx程序make

3.4)更改旧的nginx程序的名子,并复制新的程序过去,我的旧nginx程序放在/usr/sbin/目录中mv /usr/sbin/nginx /usr/sbin/nginx-20160910cp objs/nginx /usr/sbin/nginx/usr/sbin/nginx -t

执行/usr/sbin/nginx -t 命令检查配置文件并将返回下面的信息:nginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful

3.5)在nginx-1.5.6目录下执行下面的命令来升级nginxmake upgrade

3.6)执行make upgrade得到一个错误:make: /etc/nginx/sbin/nginx: Command not foundmake: *** [upgrade] Error 127

3.7)用文本编辑器打开修改nginx-1.5.6目录下名为Makefile的文件,将upgrade节点中的/etc/nginx/sbin/nginx -t改为/usr/sbin/nginx -t,保存后关闭并重新执行make upgrade命令

3.8)执行nginx -V命令,程序的版本号已经是1.5.6,升级完毕.

4.修改nginx配置文件  vim /etc/nginx/sites-available/localhostlocation ^~ /imgss/ { # root /data/customfiles/photos/; # expires 30d; accesskey off; accesskey_arg "sign"; accesskey_hashmethod md5; accesskey_signature "xxxxxxx"; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; }

accesskey 为模块开关;accesskey_hashmethod 为加密方式MD5或者SHA-1;accesskey_arg 为url中的关键字参数;accesskey_signature 为xxxxxxx加密值构成的字符串。

保存后,重启nginx :service nginx restart  ?sign=(这里为accesskey_signature MD5加密值)

再次进行测试,使用http://192.168.1.118/filefindPDFfilePath?filePath=root/(A)/12.png进行访问,将请求返回的URl /imgss/(A)/上传应用描述.docx后面添加?sign=(这里为accesskey_signature MD5加密值)

测试结果:未登录情况下 http://192.168.1.118/filefindPDFfilePath?

filePath=root/(A)/12.png http://192.168.1.118/imgss/(A)/12.png

都将返回404页面。登陆后返回正常页面,显示12.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持网页设计。

<think>我们正在讨论如何监控和查看服务器接收到的特定API请求(/api/upload 和 /api/stylize)。根据之前的上下文,我们有一个Flask应用,结构如下: - 项目根路径:假设为`stylize`(项目名) - API部分位于`app/api`目录下,并且有版本控制(如v1) - 具体到这两个请求,它们应该在`app/api/v1/img`目录下的文件中(例如`stylize.py`) 为了监控和查看服务器接收到的请求,我们可以采用以下几种方法: ### 1. 使用Flask内置的日志记录 Flask应用默认会记录每个请求到控制台(或指定的日志文件)。我们可以通过配置日志来记录这些请求的详细信息,包括请求路径、方法、IP地址、时间等。 **步骤:** - 在创建Flask应用时,配置日志级别和输出位置。 - 可以添加一个日志过滤器,只记录我们感兴趣的路径(如`/api/upload`和`/api/stylize`)。 **示例代码:** 在创建Flask应用的地方(通常是`app/__init__.py`或主应用文件)添加日志配置: ```python import logging from logging.handlers import RotatingFileHandler # 创建Flask应用实例后 app = Flask(__name__) # 配置日志 handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=1) handler.setLevel(logging.INFO) # 可以设置日志格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) app.logger.addHandler(handler) app.logger.setLevel(logging.INFO) # 如果只想记录特定路由,可以使用一个中间件(before_request)来记录 @app.before_request def log_request(): if request.path in ['/api/upload', '/api/stylize']: app.logger.info(f"Request: {request.method} {request.path} from {request.remote_addr}") ``` ### 2. 使用中间件记录请求 我们可以编写一个Flask中间件(在请求前后执行的函数)来记录请求信息。 **示例代码:** 在`before_request`钩子中记录请求: ```python @app.before_request def before_request_logging(): if request.path in ['/api/upload', '/api/stylize']: # 记录请求方法、路径、远程地址、请求参数等 app.logger.debug(f"Path: {request.path}") app.logger.debug(f"Method: {request.method}") app.logger.debug(f"Headers: {request.headers}") # 注意:记录请求体要小心,因为可能包含大文件,我们只记录非文件字段 if request.form: app.logger.debug(f"Form data: {request.form}") if request.files: app.logger.debug(f"Files: {request.files.keys()}") # 不记录文件内容,只记录文件名 ``` ### 3. 使用第三方日志监控工具 例如,使用`logstash`、`fluentd`等工具收集日志,然后通过`Kibana`等工具进行可视化监控。这需要搭建ELK(Elasticsearch, Logstash, Kibana)栈或类似工具。 ### 4. 使用APM(应用性能监控)工具 例如,使用`New Relic`、`Datadog`、`Sentry`或开源的`SkyWalking`、`Pinpoint`等。这些工具可以监控请求的详细信息,包括响应时间、错误率等,并且通常可以按路径过滤。 ### 5. 在视图函数中直接添加日志 在具体的视图函数中,我们可以添加日志记录。 例如,在`app/api/v1/img/stylize.py`中: ```python from flask import current_app as app @app.route('/api/stylize', methods=['POST']) def stylize(): app.logger.info("Received stylize request") # ... 处理请求 ... ``` ### 6. 使用调试工具 在开发环境中,可以使用Flask自带的调试器,它会记录所有请求。但生产环境中不建议开启调试模式。 ### 注意事项 - **敏感信息**:避免在日志中记录敏感信息(如密码、密钥等)以及大文件内容。 - **日志轮转**:生产环境中应配置日志轮转,防止日志文件过大。 - **日志级别**:生产环境通常使用INFO级别,避免使用DEBUG级别(除非需要调试),因为DEBUG级别日志量很大。 ### 总结 根据你的需求,最简单的方法是配置Flask的日志,并在`before_request`钩子中过滤特定的路径进行记录。这样,每当有请求到达`/api/upload`或`/api/stylize`时,就会在日志文件中记录详细信息。 如果你需要更详细的监控(如请求耗时、错误追踪等),建议使用APM工具。 §§相关问题§§ 1. 如何配置Flask日志记录到文件并按天轮转? 2. 如何在生产环境中安全地记录HTTP请求? 3. 有哪些开源的APM工具可以用于监控Flask应用?</think>要监控和查看服务器接收到的 `/api/upload` 和 `/api/stylize` 请求,可以通过以下几种方法实现: ### 1. Flask日志记录(推荐) 在视图函数中添加日志记录,这是最直接的方式: ```python # 在stylize.py文件中添加 import logging from flask import request @app.route('/api/stylize', methods=['POST']) def stylize(): # 记录请求信息 logging.info(f"[API监控] 收到/stylize请求 | 客户端IP: {request.remote_addr} | 参数: {request.form} | 文件: {request.files.keys()}") # ...原有处理逻辑... @app.route('/api/upload', methods=['POST']) def upload(): logging.info(f"[API监控] 收到/upload请求 | 客户端IP: {request.remote_addr} | 文件大小: {request.content_length}字节") # ...原有处理逻辑... ``` ### 2. 中间件拦截全局监控) 创建请求拦截器监控所有API请求: ```python # 在app/__init__.py中添加 @app.before_request def log_requests(): if request.path in ['/api/upload', '/api/stylize']: app.logger.info( f"API请求: {request.method} {request.path} " f"| IP: {request.remote_addr} " f"| 参数: {dict(request.form)}" ) ``` ### 3. 使用Nginx访问日志(生产环境推荐) 在Nginx配置中添加特定路径的日志: ```nginx # nginx.conf http { log_format api_monitor '$remote_addr - $request [$status] "$http_user_agent"'; server { location ~ ^/api/(upload|stylize) { access_log /var/log/nginx/api_access.log api_monitor; proxy_pass http://your_flask_app; } } } ``` 查看日志:`tail -f /var/log/nginx/api_access.log` ### 4. 使用监控工具 - **调试模式**:启动时添加`FLASK_DEBUG=1`,控制台会显示所有请求 - **Postman/Insomnia**:开发时手动测试API - **Prometheus+Grafana**:生产环境监控API指标 ```python # 安装prometheus_flask_exporter from prometheus_flask_exporter import PrometheusMetrics metrics = PrometheusMetrics(app) metrics.info('api_requests', 'API请求监控') ``` ### 5. 数据库记录(长期存储) ```python # 创建请求记录模型 class APIRequest(db.Model): id = db.Column(db.Integer, primary_key=True) endpoint = db.Column(db.String(50)) ip_address = db.Column(db.String(20)) timestamp = db.Column(db.DateTime, default=datetime.utcnow) # 在视图函数中 @app.route('/api/stylize') def stylize(): new_record = APIRequest(endpoint='/stylize', ip_address=request.remote_addr) db.session.add(new_record) ``` ### 查看方法 1. **实时监控**:`tail -f app.log`(查看Flask日志) 2. **历史查询**: ```bash grep "/api/stylize" app.log grep "/api/upload" /var/log/nginx/access.log ``` 3. **可视化**:使用Kibana或Grafana连接日志系统 ### 注意事项 1. 生产环境避免记录敏感数据(如文件内容、密码) 2. 高频API需注意日志体积,建议使用`RotatingFileHandler` 3. 对于文件上传,记录元数据而非文件内容: ```python logging.info(f"上传文件: {file.filename} ({file.content_length}字节)") ``` > 根据项目结构,建议在`app/api/v1/img/stylize.py`中添加视图函数级别的日志记录,这是最精准的监控方式[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值