Nginx中带GET参数的URL返回403 Forbidden错误求助
问题描述
在Nginx + PHP 8.3 + Laravel 11环境下,访问带GET参数的URL(如https://example.com?id=32或http://example.com/?page=1)时返回HTTP 403 Forbidden错误,但无参数的URL(如https://example.com/)可正常访问。当前Nginx配置如下:
server { listen 80; server_name dummy.example.com; # Redirect all HTTP traffic to HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl; server_name dummy.example.com; merge_slashes off; # SSL Configuration ssl_certificate /path/to/certificate/example.com.cer; ssl_certificate_key /path/to/certificate/example.com.key; ssl_trusted_certificate /path/to/certificate/example.com_chain.cer; # SSL Optimization ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers HIGH:!aNULL:!MD5; ssl_session_cache shared:SSL:10m; # Laravel Backend root /var/www/html/example/backend/public; index index.php index.html; # Laravel route handling location / { try_files $uri /index.php?$query_string; try_files $uri $uri/ /index.php$is_args$args; } # PHP FastCGI Configuration for Laravel location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny Access to Hidden and Sensitive Files # location ~ /\.(?!well-known).* { # deny all; # } # Logging error_log /var/log/nginx/dummy_error.log; access_log /var/log/nginx/dummy_access.log; }
问题分析与解决
核心问题
location /块中存在重复的try_files指令——Nginx在同一个location中只会执行第一条try_files,后续指令会被直接忽略。第一条try_files $uri /index.php?$query_string;的逻辑存在缺陷:当请求带参数但$uri存在时(比如根路径/),无法正确将请求参数传递给Laravel的index.php处理,进而触发403错误;同时merge_slashes off若无需特殊路径解析需求,会干扰正常的URL参数处理逻辑。
修复方案
- 移除
location /中的重复try_files,仅保留符合Laravel路由逻辑的指令; - 若无需兼容特殊路径格式,删除
merge_slashes off配置; - 调整FastCGI配置顺序,避免参数重复定义。
修改后的核心配置片段:
server { listen 443 ssl; server_name dummy.example.com; # SSL Configuration ssl_certificate /path/to/certificate/example.com.cer; ssl_certificate_key /path/to/certificate/example.com.key; ssl_trusted_certificate /path/to/certificate/example.com_chain.cer; # SSL Optimization ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers HIGH:!aNULL:!MD5; ssl_session_cache shared:SSL:10m; # Laravel Backend root /var/www/html/example/backend/public; index index.php index.html; # Laravel route handling - 修复后的路由转发逻辑 location / { try_files $uri $uri/ /index.php$is_args$args; } # PHP FastCGI Configuration for Laravel location ~ \.php$ { include fastcgi_params; include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; # 若snippets/fastcgi-php.conf已包含SCRIPT_FILENAME定义,可移除下方该行 # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # Deny Access to Hidden and Sensitive Files # location ~ /\.(?!well-known).* { # deny all; # } # Logging error_log /var/log/nginx/dummy_error.log; access_log /var/log/nginx/dummy_access.log; }
额外说明
$is_args$args是Laravel路由处理的标准写法,会正确保留请求中的GET参数并传递给index.php;- 调整FastCGI配置顺序是因为
fastcgi_params包含基础参数,后续的snippets/fastcgi-php.conf可覆盖必要设置,避免参数冲突; - 若必须保留
merge_slashes off,需确保Laravel路由配置能兼容非合并斜杠的路径解析。
内容的提问来源于stack exchange,提问作者Abdulrahman Othman
相关产品推荐
相关产品推荐

