The X-Forwarded-For Header ธรรมดาที่ไม่ธรรมดา

หลาย ๆ คนคงเคยใช้งาน HTTP Request ต่าง ๆ โดย Request เหล่านี้จะมีส่วนที่สำคัญคือ
HOST, PATH, METHOD, DATA และอีกหนึ่งส่วนที่ขาดไม่ได้คือ HEADER

HEADER คือส่วน METADATA เล็ก ๆ ที่จะส่งแนบไปคู่กับ Request เพื่อใช้เป็นข้อมูลประกอบการ Process Request อาทิ เช่น User-Agent, Cookie, Content-Type เรียกได้ว่าไม่ใช่ส่วนที่เป็น Data หลักแต่เป็นส่วนที่ต้องใช้ประกอบการ Process เช่นเราใช้ Cookie เพื่อเก็บ Session Key, Content-Type เพื่อให้รู้ว่า Request นี้เป็นรูปแบบไหน User-Agent ใช้ประกอบการ Log นอกจากนี้ HTTP Request ยังออกแบบมาเพื่อรองรับ Header อื่นๆอีกมากมาย และเรายังสามารถแทรก Header ที่เรา Custom ขึ้นมาเองได้อีกด้วย ก่อนที่จะเข้าเรื่องผมอาจขออธิบายคำศัพท์อีกสักคำนั่นคือ

Proxy Server


Proxy Server คือ Server เล็ก ๆ ที่ทำหน้ากั้นกลางระหว่าง ผู้ใช้ และ Web Service ในสมัยก่อนจะทำหน้าที่ลดภาระของ Web Service โดยจะ Cache ข้อมูลที่เรียกใช้งานซ้ำ ๆ ให้ดึงข้อมูลจาก Proxy แทนทำให้เข้าถึงข้อมูลได้เร็วขึ้น เพิ่ม Concurrent ได้มากขึ้น

ปัจจุบันได้มีการนำ Proxy มาใช้ในฝั่ง Web Service เรียกว่า Reverse Proxy การทำงานจะคล้ายกับ Proxy ธรรมดา เพียงแต่จะ ตั่งอยู่ฝั่งผู้ให้บริการ Web Service แทนที่จะตั้งอยู่ฝั่ง User แบบ Proxy ปกติ

ส่วนใหญ่ Reverse Proxy จะใช้ในกรณืที่เราทำ Load Balance หรือ Redundancy ที่มีการสร้าง Node หลาย ๆ
Instance ใน URL ตัวเดียวกัน เวลาที่มีการเปลี่ยน Node จะทำได้อย่างง่ายดายโดยที่ User ไม่จำป็นต้องเปลี่ยน Path Service ใหม่และยัง สามารถ Cache/Validate/Process ข้อมูลต่าง ๆ ก่อนส่งให้ Node ทำงานได้อีกด้วย

ปัญหาคือ หลายครั้งที่ Web Service ต้องการเข้าถึง IP Address จริงๆ ของ User แต่ไม่สามารถทำได้เพราะ Request ที่เข้ามาไม่ได้ส่งมาจาก User จริง ๆ แต่ถูกส่งมาจาก Proxy Server แทนทำให้ บน Webservice จะเห็น IP ของ Proxy แทนที่จะเป็น IP จริงของ User รวมถึงใน LOG ต่าง ๆ ก็จะเห็นเป็น IP ของ Proxy แทน

“X-Forwarded-For” Solution ที่สร้างมาเพื่อการนี้!!!!

เราสามารถแก้ปัญหาได้โดยใช้ Header tag ที่ชื่อว่า X-Forwarded-For เป็น Tag ที่ทำหน้าที่เก็บ IP Address เหมือนเป็น Stamp ว่า Request ผ่าน Client หรือ Proxy ไหนมาบ้าง โดยปกติแล้ว tag นี้จะไม่ได้ถูกส่งมาจาก Browser โดยตรงแต่มันจะถูกใส่มาให้อัตโนมัติโดย Proxy เมื่อ Request นั้นๆวิ่งผ่าน (แต่ถ้าอยากใส่มาตั้งแต่ใน Browser ก็ไม่ผิดอะไรนะครับ) เราต้องไปตั้งค่า Proxy ให้รองรับกลไกนี้ และใน Webservice ก็เปลี่ยนการเช็ค IP จาก Source Address เพียงอย่างเดียวก็ดูจาก Tag นี้ประกอบด้วย
ถ้าในกรณีมี Proxy หลายๆอันกั้นอยู่แต่ทุกอันได้เปิดการทำงานของ Tag นี้ไม่ต้องกังวลว่า ค่ามันจะทับกันนะครับ ตามปกติแล้ว Tag นี้ Proxy แต่ละตัวจะใช้วิธี Append ค่าเอา (ใส่คอมม่าคั่นและเพิ่ม IP ใหม่เข้าไป) เราก็จะรู้ว่า package นี้ผ่าน Server IP อะไรมาบ้างอีกด้วย

ตัวอย่าง Code Webservice ด้วยภาษา PHP
$ip = getenv(‘HTTP_CLIENT_IP’)?:
getenv(‘HTTP_X_FORWARDED_FOR’)?:
getenv(‘HTTP_X_FORWARDED’)?:
getenv(‘HTTP_FORWARDED_FOR’)?:
getenv(‘HTTP_FORWARDED’)?:
getenv(‘REMOTE_ADDR’);

ที่มา: https://stackoverflow.com/questions/15699101/get-the-client-ip-address-using-php

ตัวอย่าง Code Web Service ด้วย NODEJS
var clientip = req.headers[‘x-forwarded-for’] ||
req.connection.remoteAddress;

เป็นอย่างไรบ้างครับกับเกร็ดความรู้ในครั้งนี้ จริงๆแล้วมี HTTP Request อีกมากมายต่างมีบทบาทความสำคัญที่
แตกต่างกันไว้ผมจะมาเล่าให้ฟังใหม่ครับ สำหรับท่านที่สนใจบริการของ Cloud HM สามารถติดต่อเราได้ผ่านช่องทางนี้

ที่มา: https://stackoverflow.com/questions/59341481/how-to-use-x-forwarded-for-in-node-jswithout-express-if-possible

Image Credit: https://www.keycdn.com/support/x-forwarded-for