จะเพิ่มส่วนหัวการตอบกลับบน nginx เมื่อใช้ proxy_pass ได้อย่างไร


92

ฉันต้องการเพิ่มส่วนหัวที่กำหนดเองสำหรับการตอบสนองที่ได้รับจากเซิร์ฟเวอร์หลัง nginx

ในขณะที่add_headerทำงานสำหรับการตอบสนองที่ประมวลผลด้วย nginx แต่จะไม่ทำอะไรเลยเมื่อproxy_passมีการใช้


ดังนั้นคุณจึงส่งคำขอไปยังพร็อกซีและการตอบกลับชุดพร็อกซีนั้นและในการตอบกลับนี้คุณต้องการเพิ่มส่วนหัวที่กำหนดเองของคุณก่อนที่จะส่งถึงผู้ใช้นั้นถูกต้องหรือไม่?
emka86

คำตอบ:


31

มีโมดูลที่เรียกว่าHttpHeadersMoreModuleที่ให้คุณควบคุมส่วนหัวได้มากขึ้น ไม่ได้มาพร้อมกับ Nginx และต้องติดตั้งเพิ่มเติม ด้วยวิธีนี้คุณสามารถทำสิ่งนี้:

location ... {
  more_set_headers "Server: my_server";
}

ซึ่งจะ "ตั้งค่าส่วนหัวเอาต์พุตของเซิร์ฟเวอร์เป็นค่าที่กำหนดเองสำหรับรหัสสถานะและประเภทเนื้อหาใด ๆ " จะแทนที่ส่วนหัวที่ตั้งค่าไว้แล้วหรือเพิ่มหากไม่ได้ตั้งค่า


มันเป็นไปได้ที่จะเพิ่มSecureและHttpOnlyธงบนคุกกี้ตอบสนอง ? คุกกี้ตอบกลับเป้าหมายมีเฉพาะคุกกี้nameและexpireแอตทริบิวต์เท่านั้น
JPaulPunzalan

2
คุณไม่จำเป็นต้องมีไลบรารีเพื่อให้สามารถเปลี่ยนหรือเพิ่มส่วนหัวของการตอบกลับได้และตรงกันข้ามกับคำตอบที่ได้รับการโหวตมากที่สุดที่คุณสามารถแทนที่ส่วนหัวได้คุณเพียงแค่ต้องลบออกก่อน ตรวจสอบคำตอบของฉันด้านล่างสำหรับรายละเอียด
เหี่ยว

162

add_headerใช้งานได้ดีproxy_passโดยไม่มี วันนี้ฉันเพิ่งตั้งค่าการกำหนดค่าที่ฉันใช้คำสั่งนั้น ฉันต้องยอมรับว่าแม้ว่าฉันจะพยายามดิ้นรนเช่นกันในการตั้งค่านี้โดยไม่ได้นึกถึงเหตุผล

ตอนนี้ฉันมีการกำหนดค่าที่ใช้งานได้และมีสิ่งต่อไปนี้ (อื่น ๆ ):

server {
    server_name  .myserver.com
    location / {
        proxy_pass  http://mybackend;
        add_header  X-Upstream  $upstream_addr;
    }
}

ก่อน Nginx 1.7.5 add_headerทำงานเฉพาะในการตอบสนองที่ประสบความสำเร็จในทางตรงกันข้ามกับHttpHeadersMoreModuleกล่าวโดยเซบาสเตียนกู๊ดแมนในคำตอบของเขา

เนื่องจาก nginx 1.7.5คุณสามารถใช้คำหลักalwaysเพื่อรวมส่วนหัวที่กำหนดเองได้แม้ในการตอบสนองข้อผิดพลาด ตัวอย่างเช่น:

add_header X-Upstream $upstream_addr always;

ข้อ จำกัด :คุณไม่สามารถแทนที่ค่าใช้ส่วนหัวserveradd_header


41
เนื่องจาก nginx 1.7.5 คุณสามารถใช้ "always" เพื่อรวมส่วนหัวที่กำหนดเองในการตอบสนองข้อผิดพลาดโดยใช้ add_header:add_header X-Upstream $upstream_addr always;
Shane

อย่างไรก็ตามหากต้องการมีฟังก์ชันการทำงานที่คล้ายคลึงกันโดยไม่เปิดเผยการรวม IP / พอร์ตของเซิร์ฟเวอร์พร็อกซี เช่นX-Upstream: 10.10.10.10เทียบกับX-Upstream: 53c2d28edefdf501ab7c92e02a0c1687(md5 อาจไม่เป็นประโยชน์ในการปิดบังโครงสร้างพื้นฐาน แต่มันบ่งบอกถึงแนวคิด)
zamnuts

@zamnuts: การส่งผ่าน IP ต้นน้ำและหมายเลขพอร์ตเป็นเพียงตัวอย่างของการใช้add_headerคำสั่ง คุณไม่จำเป็นต้องส่งเลย
Oliver

@ โอลิเวอร์ฉันทราบดี แต่ฉันกำลังสอบถามเกี่ยวกับตัวระบุอัพสตรีมที่เป็นทางเลือกอื่น ๆ นอกเหนือจากหมายเลข IP / พอร์ตหรือการทำให้สับสน บางทีคำถามของฉันอยู่นอกขอบเขตและฉันควรสร้างโพสต์ใหม่ :)
zamnuts

@zamnuts: ฉันขอแนะนำให้ถามคำถามใหม่ด้วย :-)
Oliver

25

ตามที่โอลิเวอร์เขียน:

add_headerใช้งานได้ดีproxy_passโดยไม่มี

อย่างไรก็ตามตามที่ Shane เขียนใน Nginx 1.7.5 คุณจะต้องผ่านalwaysเพื่อที่จะได้รับadd_headerการตอบสนองข้อผิดพลาดดังนี้:

add_header  X-Upstream  $upstream_addr always;

5
ฉันใช้เวลานานสงสัยว่าทำไมส่วนหัวของฉันไม่แสดงพยายามย้ายไปไว้ในบล็อกเซิร์ฟเวอร์บล็อกตำแหน่ง ... และนี่คือเหตุผล: nginx ไม่ได้เพิ่มไว้ในการตอบสนองข้อผิดพลาด: F ขอบคุณ
Shautieh

ฉันก็เช่นกัน :) และแม้ว่าคำตอบนี้จะเกิดขึ้นกับฉันเมื่อวันก่อนอีกครั้ง ต้องทบทวนคำตอบของตัวเอง
Dmitry Minkovsky

ดูnginx.org/en/docs/http/ngx_http_headers_module.html#add_headerสำหรับรายละเอียด
Steve Eynon

16

ซ่อนส่วนหัวของการตอบกลับแล้วเพิ่มค่าส่วนหัวที่กำหนดเองใหม่

การเพิ่มส่วนหัวที่ใช้add_headerงานได้ดีกับพร็อกซีพาส แต่ถ้ามีค่าส่วนหัวที่มีอยู่ในการตอบสนองก็จะซ้อนค่า

หากคุณต้องการตั้งค่าหรือแทนที่ค่าส่วนหัว (เช่นแทนที่Access-Control-Allow-Originส่วนหัวเพื่อให้ตรงกับไคลเอนต์ของคุณเพื่ออนุญาตการแชร์ทรัพยากรข้ามแหล่งที่มา) คุณสามารถทำได้ดังนี้:

# 1. hide the Access-Control-Allow-Origin from the server response
proxy_hide_header Access-Control-Allow-Origin;
# 2. add a new custom header that allows all * origins instead
add_header Access-Control-Allow-Origin *;

เมื่อproxy_hide_headerรวมเข้ากับadd_headerจะช่วยให้คุณมีอำนาจในการกำหนด / แทนที่ค่าส่วนหัวการตอบสนอง

คำตอบที่คล้ายกันสามารถพบได้ที่นี่บน ServerFault

อัพเดท:

หมายเหตุ: proxy_set_headerมีไว้สำหรับการตั้งค่าส่วนหัวของคำขอก่อนที่จะส่งคำขอต่อไปไม่ใช่สำหรับการตั้งค่าส่วนหัวการตอบกลับ (แอตทริบิวต์การกำหนดค่าสำหรับส่วนหัวเหล่านี้อาจทำให้สับสนเล็กน้อย)


ขอบคุณความช่วยเหลือที่ดี
Lancer

14

คุณสามารถลองวิธีนี้:

ในlocationบล็อกของคุณเมื่อคุณใช้proxy_passทำสิ่งนี้:

location ... {

  add_header yourHeaderName yourValue;
  proxy_pass xxxx://xxx_my_proxy_addr_xxx;

  # Now use this solution:
  proxy_ignore_headers yourHeaderName // but set by proxy

  # Or if above didn't work maybe this:
  proxy_hide_header yourHeaderName // but set by proxy

}

ฉันไม่แน่ใจว่าจะเป็นสิ่งที่คุณต้องการหรือไม่ แต่ลองใช้วิธีนี้และผลลัพธ์อาจจะตรงกับปัญหาของคุณ

นอกจากนี้คุณสามารถใช้ชุดค่าผสมนี้:

proxy_hide_header headerSetByProxy;
set $sent_http_header_set_by_proxy yourValue;

6
ฉันต้องใช้วิธีนี้เนื่องจาก nginx กำลังเพิ่มส่วนหัวที่ซ้ำกันแทนที่จะเขียนทับส่วนที่ออก location / { proxy_pass http://127.0.0.1:8080/; proxy_hide_header "Access-Control-Allow-Origin"; if ($http_origin ~* "^https://(example.com|www.example.com)$") { add_header Access-Control-Allow-Origin "$http_origin"; } }
ether6
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.