You need to enable JavaScript to run this app. Nginx能否基于TCP socket做单次授权透传后续所有HTTP请求?
优惠活动
大模型
产品
解决方案
定价
更多

Nginx能否基于TCP socket做单次授权透传后续所有HTTP请求?

Nginx HTTP/2 连接级授权实现方案

原生Nginx的auth_request模块默认是请求级校验,每一个HTTP请求都会触发一次后端授权调用,没有内置的连接级授权能力,但可以通过扩展模块实现你要的「TCP连接建立时仅校验一次、同连接后续所有HTTP请求直接放行」的效果,两种主流实现方案如下:

方案1:基于OpenResty Lua 模块实现(兼容性最好)

依赖OpenResty发行版或者已编译ngx_http_lua_module的Nginx,通过共享内存缓存连接授权结果:

http {
    # 定义10M共享内存缓存区,可存储数万条连接授权记录
    lua_shared_dict conn_auth_cache 10m;
    # HTTP/2 空闲连接超时时间,和缓存过期时间对齐
    http2_idle_timeout 300s;

    server {
        listen 443 ssl http2;
        # 其他站点配置省略

        location /somewhere_restricted {
            access_by_lua_block {
                local conn_id = ngx.var.connection
                local auth_cache = ngx.shared.conn_auth_cache
                -- 优先查询当前连接是否已有授权记录
                local is_authed = auth_cache:get(conn_id)
                if is_authed then
                    return -- 已授权直接放行
                end
                -- 无授权记录则调用后端授权接口
                local auth_res = ngx.location.capture("/isallowed")
                if auth_res.status == 200 then
                    -- 授权通过,缓存结果300秒,和HTTP/2空闲超时对齐
                    auth_cache:set(conn_id, 1, 300)
                    return
                end
                -- 授权失败返回401
                return ngx.exit(401)
            }
        }

        location = /isallowed {
            internal;
            proxy_pass http://backend_auth;
            # 不需要传递请求体,减少授权请求开销
            proxy_pass_request_body off;
            proxy_set_header Content-Length "";
        }
    }
}

方案2:基于Nginx官方ngx_http_keyval_module实现(无Lua依赖)

需要Nginx版本≥1.19.8,无需额外编译Lua模块,配置更简洁:

http {
    # 定义连接授权缓存区,10M容量,缓存自动过期时间300s
    keyval_zone zone=conn_auth:10M timeout=300s;
    # 绑定连接ID为缓存key,$conn_auth_ok为缓存值(标识是否授权通过)
    keyval $connection $conn_auth_ok zone=conn_auth;
    # HTTP/2 空闲超时和缓存过期时间对齐
    http2_idle_timeout 300s;

    server {
        listen 443 ssl http2;
        # 其他站点配置省略

        location /somewhere_restricted {
            # 当前连接已有授权记录直接放行
            if ($conn_auth_ok = 1) {
                break;
            }
            # 无授权记录走auth_request校验
            auth_request /isallowed;
            # 校验通过后写入缓存
            auth_request_set $conn_auth_ok 1;
        }

        location = /isallowed {
            internal;
            proxy_pass http://backend_auth;
        }
    }
}

注意事项

  • 上述方案仅适用于单个HTTP/2连接归属于单个用户的场景,如果客户端是代理服务、会复用连接传递多个用户的请求,会出现权限串用问题,需要业务侧保证连接和用户的绑定关系
  • 缓存过期时间建议和http2_idle_timeout严格对齐,避免连接断开后缓存残留浪费存储空间
  • 该逻辑和WebSocket场景的授权逻辑本质一致:均是在长连接建立阶段完成一次性校验,后续同连接的所有流量直接放行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 23:54:03