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

在Nginx反向代理中兼容Basic Auth与Bearer Token的方案咨询

问题描述

使用Nginx作为反向代理,前端与NestJS后端通过Bearer Token实现用户认证。配置auth_basic限制环境访问后,由于请求中同时存在Basic和Bearer两种Authentication请求头,导致Nginx转发时出现冲突,后端无法正常处理Bearer Token认证。

当前Nginx配置:

upstream frontend {
    server frontend:4200;
}

upstream backend {
    server backend:4000;
}

server {
    listen 80;
    location / {
        auth_basic "Restricted";
        auth_basic_user_file  /etc/nginx/.htpasswd;

        proxy_pass http://frontend;
    }

    location /api {
        rewrite /api/(.*) /$1 break;
        proxy_pass http://backend;
    }
}
解决方案

方案1:转发后端请求时仅保留Bearer Token头

通过Nginx的map指令提取请求头中的Bearer Token信息,转发后端时只传递该头,丢弃Basic认证的头。

修改后的配置:

# 在server块外部定义map规则
map $http_authorization $bearer_auth {
    # 匹配以Bearer开头的Authorization头
    ~*^Bearer\s+ $http_authorization;
    # 其他情况清空Authorization头
    default "";
}

upstream frontend {
    server frontend:4200;
}

upstream backend {
    server backend:4000;
}

server {
    listen 80;
    location / {
        auth_basic "Restricted";
        auth_basic_user_file  /etc/nginx/.htpasswd;

        proxy_pass http://frontend;
    }

    location /api {
        rewrite /api/(.*) /$1 break;
        # 仅传递Bearer Token的Authorization头
        proxy_set_header Authorization $bearer_auth;
        proxy_pass http://backend;
    }
}

方案2:使用Cookie保持Nginx的Basic认证状态

让Nginx验证Basic认证后,通过Cookie记录认证状态,后续请求不再携带Basic的Authorization头,避免与Bearer Token冲突。

修改后的配置:

upstream frontend {
    server frontend:4200;
}

upstream backend {
    server backend:4000;
}

server {
    listen 80;
    # 定义Cookie名称和过期时间
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
    auth_basic_use_cache off;
    # 设置认证Cookie,有效期1天
    add_header Set-Cookie "nginx_auth=valid; Path=/; Max-Age=86400; HttpOnly";

    location / {
        # 检查Cookie是否存在,存在则跳过auth_basic
        if ($cookie_nginx_auth = "valid") {
            auth_basic off;
        }
        proxy_pass http://frontend;
    }

    location /api {
        rewrite /api/(.*) /$1 break;
        # 同样检查Cookie,跳过auth_basic
        if ($cookie_nginx_auth = "valid") {
            auth_basic off;
        }
        proxy_pass http://backend;
    }
}

方案3:后端兼容处理多个Authentication头

如果可以修改NestJS后端代码,让服务优先解析Bearer Token头,忽略Basic认证头。例如在认证拦截器中:

// NestJS 认证拦截器示例
@Injectable()
export class AuthInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    // 提取Bearer Token,优先取包含Bearer的头
    const authHeader = request.headers.authorization?.split(',')
      .find(h => h.trim().startsWith('Bearer'));
    if (authHeader) {
      request.headers.authorization = authHeader.trim();
    }
    return next.handle();
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:01:03