nginx服务器怎样向cookies里面添加数据
作者:焦点 来源:百科 浏览: 【大 中 小】 发布时间:2026-10-17 06:20:19 评论数:
Nginx 本身不生成 Cookie,面添它只负责转发或修改 HTTP 头。加数据你要往 Cookie 里塞数据,面添得靠 add_header 指令,加数据或者用 proxy_cookie_path 这类模块做间接操作。面添最直接的加数据办法是在 location 块里写一行:
add_header Set-Cookie "user_id=12345; Path=/; HttpOnly"; 这行配置会让 Nginx 在响应给客户端时,往 Set-Cookie 头里追加一个名为 user_id、面添值为 12345 的加数据 Cookie。客户端下次请求就会带上它。面添但注意,加数据add_header 默认只在 200、面添201、加数据204、面添206、加数据301、面添302、303、304、307、308 这些状态码下生效。如果你在 404 页面里加 Cookie,得显式加上 always 参数:
add_header Set-Cookie "debug=1; Path=/" always; 我见过有人试图在 if 块里动态拼 Cookie 值,比如根据 $arg_token 生成。Nginx 的 add_header 不支持变量拼接字符串吗?支持,但有限制。你可以写:
add_header Set-Cookie "token=$arg_token; Path=/"; 只要 $arg_token 来自 URL 参数,Nginx 就会在响应时替换成实际值。但别高兴太早——如果 $arg_token 里包含分号或换行,可能破坏 Cookie 结构。实际生产里我建议用 map 做一层过滤:
map $arg_token $safe_token { default ""; "~^[a-zA-Z0-9]+$" $arg_token; } 然后 add_header Set-Cookie "token=$safe_token; Path=/";。这样只允许字母数字,避免注入。
另一个常见需求:后端已经设置了一个 Cookie,但你想在 Nginx 层再追加一个。比如后端返回 Set-Cookie: session=abc,你希望再加一个 env=prod。直接写两个 add_header 会怎样?Nginx 会把它们合并成两个 Set-Cookie 头,浏览器会分别处理。但注意,add_header 是追加,不是覆盖。如果后端已经设置了同名 Cookie,Nginx 再加一个同名的,浏览器可能只认最后一个,或者两个都存——取决于路径和域。我实测过 Chrome,同名的两个 Set-Cookie 如果路径相同,后者覆盖前者。
想修改已有 Cookie 的值?Nginx 没有直接改 Set-Cookie 的指令。你得用 proxy_cookie_path 改路径,或者用 sub_filter 模块替换响应体里的内容——但那不是改头。更彻底的办法是上 lua-nginx-module,用 ngx.header["Set-Cookie"] 直接操作。比如:
location / { rewrite_by_lua_block { ngx.header["Set-Cookie"] = "injected=1; Path=/; HttpOnly" } proxy_pass http://backend; } 这会把后端的所有 Set-Cookie 覆盖掉。想追加,得先读再拼:
local cookies = ngx.resp.get_headers()["Set-Cookie"] if cookies then ngx.header["Set-Cookie"] = { cookies, "injected=1; Path=/" } else ngx.header["Set-Cookie"] = "injected=1; Path=/" end 注意 ngx.resp.get_headers() 拿到的是 table 或字符串,取决于 Nginx 版本。我踩过坑:在 OpenResty 1.19 里,如果只有一个 Set-Cookie,它返回字符串,多个才返回 table。所以得判断类型。
还有一点:add_header 不会影响 proxy_pass 返回的 Set-Cookie,它是独立追加的。但如果你在 location 里同时用了 add_header 和 proxy_pass,且后端也设置了 Set-Cookie,最终响应里会有多个 Set-Cookie 头。用 curl -I 能看到。浏览器处理多个同名 Cookie 时,路径更具体的优先,路径相同则后设置的覆盖先设置的。
实际案例:我帮一个朋友调 API 网关,需要在 Nginx 层给所有响应打一个 trace_id Cookie。他用了 add_header Set-Cookie "trace_id=$request_id; Path=/; SameSite=Lax";。结果发现 $request_id 是 Nginx 内置变量,但默认没开。得在 http 块里加 map $request_id $trace_id { default $request_id; } 才行。或者直接用 $request_id,Nginx 1.11.0 之后才有。老版本得自己生成。
最后提醒:Cookie 值里不要放敏感信息,Nginx 的 add_header 是明文写入响应头的。想加密?那得在应用层做,Nginx 只负责搬运。
