我一直在绞尽脑汁试图解决 Chrome 独有的 403 问题。我有一个在 tomcat8 中运行的应用程序,我用 Nginx 来引导它。该机器托管在客户端上,我怀疑环境中可能存在某些问题,但我需要一些东西来返回给他们。
我可以登录到应用程序。我有一个搜索页面,它使一些 jquery ajax 调用 rest api,我得到了 403。
在 Firefox 和 IE 上一切正常。但在 Chrome 和 Safari 上,我得到了 403。
我以为这可能是 CORS 的问题,因为我是从 ajax 发出调用的。在 Chrome 上禁用网络安全没有任何作用。所以我不相信是那样的。
这是我的配置
Nginx配置文件
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/proxy_params;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
我的服务器.conf
server {
server_name myapp.mydomain.com;
root /var/www/tomcat8/webapps/myapp/;
location / {
index index.html index.jsp;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080/;
}
}
server {
listen 80;
server_name myapp.mydomain.com;
return 404; # managed by Certbot
}
以下是我服务调用时出现 403 错误的 nginx 日志条目
172.16.1.1 - - [19/Jul/2019:16:30:49 -0400] "POST /myap/services/search/lookupUI? HTTP/1.1" 403 0 "https://myapp.mydomain.com/myapp/gui/findpatients.jsp" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
nginx 日志中的服务调用同时具有 GET 和 POST 选项。我可以在浏览器地址栏上传递 GET,它就可以工作了。
我不知道这可能是什么。这是一个非常简单的 nginx 代理配置,我将其与其他客户端一起使用。
任何帮助将非常感激。
答案1
总结
使用 proxy_pass 指令将其添加到服务器块
proxy_set_header Origin "";
过程
我遇到了同样的问题,在谷歌搜索时发现了您的帖子。在放弃寻找快速解决方案后,我做了以下事情。
首先,我检查了请求是否到达了 tomcat。(我对 tomcat 使用 docker,所以我的接口是 docker0。使用它ifconfig
来帮助确定你的请求通过了哪个接口)
这将在终端中以相当不友好的格式显示请求
sudo tcpdump -i docker0 -nnSX port 8080
这将在当前目录中创建一个文件“dump.pcap”,你可以将其复制到装有 Wireshark 的机器上,然后用它查看它
sudo tcpdump -i docker0 -w dump.pcap port 8080
我看到请求顺利通过,但 Tomcat 不喜欢这样,在请求到达我的 Java 代码之前就拒绝了它们。
然后,我使用 Firefox 和 Chrome 上的开发人员工具 (ctrl - shift - i) 检查了实际请求。转到“网络”选项卡并查找失败的请求。查找“请求标头”,然后单击 Firefox 上的“原始标头”或 Chrome 上的“查看源代码”,然后将其复制到 notepad++ 或其他可以对行进行排序的编辑器中。(编辑 -> 行操作 -> 按字典顺序对行进行排序)
为了再次确认是否确实是标头差异导致了此问题,我使用 Postman 针对失败的 URL 测试了两组标头。Postman 中有一个针对标头的批量编辑功能,您只需粘贴标头即可。
只需排除法即可找出导致错误的标头。我首先考虑修改我的 Javascript 代码,以某种方式使 Chrome 不发送 Origin 标头,但我认为让 Nginx 删除标头更简单、更可靠。快速在 Google 上搜索如何做到这一点,然后你就找到了。
希望这对你有帮助!
答案2
最终对我有用的是添加这个代理指令 proxy_set_header Host $http_host;
我还清理了一些不需要的东西这是最终的配置
server {
server_name myapp.mydomain.com;
root /var/www/tomcat8/webapps/myapp/;
location / {
index index.html index.jsp;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080/;
}
listen 80;
}