วิธีใช้งาน
- ป้อนชื่อผู้ใช้และรหัสผ่าน
- คัดลอกส่วนหัว Authorization ที่สร้างขึ้นไปใช้ในไคลเอนต์ของคุณ หรือใช้คำสั่ง curl เพื่อทดสอบคำขอ
- หากต้องการอ่านส่วนหัวที่มีอยู่ ให้วางลงในส่วน “ถอดรหัสส่วนหัวที่มีอยู่” แล้วชื่อผู้ใช้และรหัสผ่านจะแสดงขึ้นมา
การยืนยันตัวตนแบบ HTTP Basic ทำงานอย่างไร
การยืนยันตัวตนแบบ Basic กำหนดไว้ใน RFC 7617 เมื่อทรัพยากรได้รับการป้องกัน เซิร์ฟเวอร์จะตอบกลับด้วย 401 Unauthorized และส่วนหัว WWW-Authenticate: Basic realm="..." จากนั้นไคลเอนต์จะนำชื่อผู้ใช้และรหัสผ่านมาต่อกันโดยคั่นด้วยทวิภาค เข้ารหัสผลลัพธ์เป็น Base64 แล้วส่งไปกับทุกคำขอ:
Authorization: Basic base64(username ":" password)
# ตัวอย่างจาก RFC 7617: ผู้ใช้ "Aladdin" รหัสผ่าน "open sesame"
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
เบราว์เซอร์จัดการขั้นตอนนี้เองและแสดงหน้าต่างเข้าสู่ระบบ ส่วนสคริปต์และไคลเอนต์ API มักส่งส่วนหัวไปพร้อมคำขอแรกโดยไม่รอให้เซิร์ฟเวอร์ร้องขอ (challenge) เนื่องจากทวิภาคใช้คั่นค่าทั้งสอง ชื่อผู้ใช้จึงต้องไม่มีทวิภาค แต่รหัสผ่านมีได้ เซิร์ฟเวอร์สามารถเพิ่ม charset="UTF-8" ลงใน challenge เพื่อแจ้งว่าข้อมูลรับรองที่มีอักขระนอกเหนือจาก ASCII ต้องเข้ารหัสเป็น UTF-8
Base64 ไม่ใช่การเข้ารหัสลับ
ส่วนหัวนี้ดูเหมือนข้อความที่อ่านไม่ออก แต่ใครก็ตามที่เห็นก็กู้รหัสผ่านคืนได้ในไม่กี่วินาที ด้วยตัวถอดรหัสในหน้านี้หรือตัวถอดรหัส Base64ใดก็ได้ การยืนยันตัวตนแบบ Basic จึงยอมรับได้เฉพาะเมื่อใช้ผ่าน HTTPS ซึ่ง TLS จะเข้ารหัสลับส่วนหัวระหว่างการส่ง นอกจากนี้ควรคำนึงว่า
- ข้อมูลรับรองถูกส่งไปกับทุกคำขอ คำขอผ่าน HTTP ธรรมดาเพียงครั้งเดียวก็ทำให้ข้อมูลรั่วไหลได้
- พร็อกซี โหลดบาลานเซอร์ และเครื่องมือดีบักอาจบันทึกส่วนหัว
Authorizationลงในล็อก หากไม่ได้ตั้งค่าไม่ให้บันทึก - เบราว์เซอร์จะจำข้อมูลรับรองที่ป้อนไว้จนกว่าจะปิดเบราว์เซอร์ และไม่มีวิธีออกจากระบบที่เป็นมาตรฐาน
สำหรับ API สาธารณะ โทเค็น API ที่เพิกถอนได้หรือ OAuth เป็นทางเลือกที่เหมาะสมกว่า ส่วนการยืนยันตัวตนแบบ Basic ยังเป็นตัวเลือกที่สมเหตุสมผลสำหรับเครื่องมือภายใน เว็บไซต์ทดสอบ (staging) และการเรียกระหว่างเซิร์ฟเวอร์ผ่าน TLS
การส่งส่วนหัวจากโค้ด
# curl สร้างส่วนหัวให้เอง
curl -u 'user:password' https://api.example.com/
// JavaScript fetch (btoa รองรับเฉพาะอักขระ Latin-1)
fetch(url, { headers: { Authorization: 'Basic ' + btoa('user:password') } })
# Python requests
requests.get(url, auth=('user', 'password'))
หลีกเลี่ยงการฝังข้อมูลรับรองไว้ใน URL เช่น https://user:password@host/ เพราะ RFC 3986 เลิกสนับสนุนรูปแบบนี้แล้ว ข้อมูลจะไปปรากฏในประวัติของเบราว์เซอร์และล็อกของเซิร์ฟเวอร์ และเบราว์เซอร์สมัยใหม่ก็จำกัดการใช้งานรูปแบบนี้
คำถามที่พบบ่อย
จะถอดรหัสส่วนหัว Basic Auth ได้อย่างไร
วางส่วนหัวลงในส่วน “ถอดรหัสส่วนหัวที่มีอยู่” แล้วชื่อผู้ใช้และรหัสผ่านจะปรากฏทันที ตัวถอดรหัส Base64 ใด ๆ ก็ให้ผลลัพธ์เดียวกัน และนี่คือเหตุผลที่ส่วนหัวนี้ต้องส่งผ่าน HTTPS เท่านั้น
รหัสผ่านมีทวิภาคได้หรือไม่
ได้ เซิร์ฟเวอร์จะแยกค่าที่ถอดรหัสแล้วตรงทวิภาคตัวแรก ทุกอย่างที่อยู่หลังทวิภาคนั้นจึงเป็นส่วนของรหัสผ่าน แต่ชื่อผู้ใช้ต้องไม่มีทวิภาค
การยืนยันตัวตนแบบ HTTP Basic ปลอดภัยหรือไม่
เมื่อใช้ผ่าน HTTPS ร่วมกับรหัสผ่านที่รัดกุมและไม่ซ้ำกับที่อื่น ข้อมูลรับรองจะได้รับการปกป้องระหว่างการส่ง แต่ข้อมูลนี้ถูกส่งไปกับทุกคำขอ และหมดอายุแบบโทเค็นไม่ได้ ห้ามใช้ผ่าน HTTP ธรรมดาเด็ดขาด
ทำไมจึงเข้าสู่ระบบไม่ได้เมื่อรหัสผ่านมีอักขระที่มีเครื่องหมายกำกับหรืออักขระที่ไม่ใช่ละติน
charset="UTF-8" หากไม่มีการประกาศ เซิร์ฟเวอร์รุ่นเก่าอาจถือว่าเป็น ISO-8859-1 และนำไบต์ที่ต่างกันมาเปรียบเทียบรหัสผ่านถูกส่งไปที่ใดหรือไม่
ไม่ถูกส่ง ส่วนหัวถูกสร้างด้วย JavaScript ในเบราว์เซอร์ของคุณ และไม่มีการส่งข้อมูลใด ๆ ออกไป อย่างไรก็ตาม ควรใช้ข้อมูลรับรองสำหรับทดสอบเมื่อแชร์คำสั่ง curl ที่สร้างขึ้นให้ผู้อื่น