You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx中limit_except+rewrite实现非POST/PUT请求鉴权遇404问题

Fixing Nginx Rewrite + limit_except 404 Issue

I've run into this exact problem before—when combining limit_except with rewrite rules in the same location block, Nginx can sometimes drop the rewritten URI when proxying, leading to those frustrating 404s. Here's what's going wrong and how to fix it:

Why This Happens

The core issue is how Nginx processes limit_except alongside rewrite rules. When you place rewrite and limit_except in the same location, the rewritten URI doesn't always get properly passed to the proxy for requests that trigger the limit_except block (i.e., non-POST/PUT requests). This is because limit_except creates an internal sub-request context that can override or ignore the earlier rewrite.

Solution 1: Nested Location with Internal Redirect (Most Reliable)

The cleanest fix is to split the URI rewrite and authentication into separate locations using an internal redirect. This ensures the rewritten URI is preserved before applying authentication:

# Handle external URI rewrite first
location /apis/app/ {
    rewrite ^/apis/app/(.*)$ /api-internal/$1 last;
}

# Internal location for proxying + authentication
location /api-internal/ {
    internal; # Restricts access to only internal requests (prevents direct hits)
    
    limit_except POST PUT {
        auth_basic "Restricted";
        auth_basic_user_file /var/www/html/apps/app/.htpasswd;
    }

    # Rewrite the internal URI to match your API's expected path
    rewrite ^/api-internal/(.*)$ /$1 break;
    
    proxy_pass http://my_adress;
    proxy_redirect off;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    add_header tokentooap app;
    limit_req zone=one;
}

location /apps/app/ {
    try_files $uri $uri/ /apps/app/index.html;
}

Solution 2: Duplicate Rewrite Rules (Simpler, Edge Cases Possible)

If you prefer to keep everything in one location, you can duplicate the rewrite rule inside the limit_except block to ensure it runs for authenticated requests too:

location /apis/app/ {
    # Base rewrite and proxy config for POST/PUT
    rewrite ^/apis/app/(.*)$ /$1 break;
    proxy_pass http://my_adress;
    proxy_redirect off;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    add_header tokentooap app;
    limit_req zone=one;

    # Auth + rewrite for non-POST/PUT methods
    limit_except POST PUT {
        rewrite ^/apis/app/(.*)$ /$1 break;
        auth_basic "Restricted";
        auth_basic_user_file /var/www/html/apps/app/.htpasswd;
    }
}

location /apps/app/ {
    try_files $uri $uri/ /apps/app/index.html;
}

Note: This approach can have edge cases depending on your Nginx version and other adjacent configs, so the nested location method is generally the safer bet.

Key Checks After Fixing

  • Test with GET, DELETE, HEAD requests to confirm the auth prompt appears and the API routes correctly
  • Verify POST/PUT requests bypass auth and still reach the right endpoints
  • Check Nginx error logs (/var/log/nginx/error.log) if you still see 404s—they’ll often clue you in on URI mismatches

内容的提问来源于stack exchange,提问作者ArrowHeadDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:52:35