การเข้าสู่ระบบ RESTful ล้มเหลว: ส่งคืน 401 หรือการตอบกลับที่กำหนดเอง


103

นี่เป็นคำถามเชิงแนวคิด

ฉันมีแอปพลิเคชันไคลเอนต์ (มือถือ) ที่ต้องการรองรับการล็อกอินกับบริการเว็บ RESTful เนื่องจากบริการบนเว็บเป็น RESTful จำนวนนี้จะทำให้ลูกค้ายอมรับชื่อผู้ใช้ / รหัสผ่านจากผู้ใช้ยืนยันชื่อผู้ใช้ / รหัสผ่านนั้นกับบริการจากนั้นจำไว้ว่าจะส่งชื่อผู้ใช้ / รหัสผ่านนั้นพร้อมกับคำขอที่ตามมาทั้งหมด

การตอบกลับอื่น ๆ ทั้งหมดในบริการเว็บนี้มีให้ในรูปแบบ JSON

คำถามคือเมื่อฉันสอบถามบริการเว็บเพียงเพื่อดูว่าชื่อผู้ใช้ / รหัสผ่านที่ระบุนั้นถูกต้องหรือไม่บริการเว็บควรตอบกลับด้วยข้อมูล JSON เสมอเพื่อบอกฉันว่าประสบความสำเร็จหรือไม่สำเร็จหรือควรส่งคืน HTTP 200 ในข้อมูลประจำตัวและ HTTP ที่ดี 401 ในข้อมูลประจำตัวที่ไม่ถูกต้อง

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

พูดอีกอย่างสำหรับฉันดูเหมือนว่าคำขอเช่น:

myservice.com/this/is/a/user/action 

ควรส่งคืน 401 หากมีการให้ข้อมูลรับรองที่ไม่ถูกต้อง แต่คำขอเช่น:

myservice.com/are/these/credentials/valid

ไม่ควรส่งคืน 401 เนื่องจาก URL นั้น (คำขอ) นั้นได้รับอนุญาตโดยมีหรือไม่มีข้อมูลรับรองที่ถูกต้อง

ฉันต้องการรับฟังความคิดเห็นที่เป็นธรรมไม่ทางใดก็ทางหนึ่ง วิธีมาตรฐานในการจัดการสิ่งนี้คืออะไรและเป็นวิธีมาตรฐานในการจัดการกับสิ่งนี้อย่างมีเหตุผลหรือไม่?

คำตอบ:


128

ก่อนอื่น 401 คือรหัสตอบกลับที่เหมาะสมในการส่งเมื่อเกิดการเข้าสู่ระบบที่ล้มเหลว

401 ไม่ได้รับอนุญาต คล้ายกับ 403 Forbidden แต่ใช้เฉพาะเมื่อจำเป็นต้องมีการตรวจสอบสิทธิ์และล้มเหลวหรือยังไม่ได้ให้ การตอบกลับต้องมีฟิลด์ส่วนหัว WWW-Authenticate ที่มีความท้าทายที่เกี่ยวข้องกับทรัพยากรที่ร้องขอ

ความสับสนของคุณเกี่ยวกับmyservice.com/are/these/credentials/validการส่งกลับ 401 เมื่อคุณเพิ่งตรวจสอบฉันคิดว่าขึ้นอยู่กับความจริงที่ว่าการทำคำขอบูลีนใน REST มักจะผิดโดยข้อ จำกัด RESTful ทุกคำขอควรส่งคืนทรัพยากร การทำคำถามบูลีนในบริการ RESTful เป็นเรื่องลื่นไหลไปที่ RPC

ตอนนี้ฉันไม่รู้ว่าบริการที่คุณดูนั้นมีพฤติกรรมอย่างไร แต่วิธีที่ดีในการแก้ปัญหานี้คือการมีวัตถุบัญชีที่คุณพยายาม GET หากข้อมูลรับรองของคุณถูกต้องคุณจะได้รับวัตถุบัญชีหากคุณไม่ต้องการเสียแบนด์วิดท์เพียงเพื่อ "ตรวจสอบ" คุณสามารถทำ HEAD ในทรัพยากรเดียวกันได้

แอคเคาต์ออบเจ็กต์ยังเป็นสถานที่ที่ดีในการจัดเก็บค่าบูลีนที่น่ารำคาญเหล่านั้นซึ่งอาจเป็นเรื่องยุ่งยากในการสร้างทรัพยากรแต่ละรายการ


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

3
วิธีการมองของคุณนั้นถูกต้อง คุณไม่จำเป็นต้องได้รับการรับรองความถูกต้องจึงจะสามารถขอวัตถุบัญชีของคุณได้ แต่คุณต้องตรวจสอบสิทธิ์ให้สำเร็จจึงจะสามารถรับทรัพยากรได้และนั่นauthentication is required and has failed or has not yet been providedจะใช้ได้ที่ไหนเนื่องจากคุณไม่ได้ขอความถูกต้องของข้อมูลรับรอง แต่สำหรับทรัพยากรเฉพาะตามข้อมูลรับรองที่คุณระบุ
พระ

2
ฉันเข้าใจว่าเหตุใดคุณจึงต้องการ "ตรวจสอบการโทร" และด้วยเหตุนี้ฉันจึงยังคงส่งเสริม 401 เป็นรหัสตอบกลับที่เหมาะสมสำหรับการตรวจสอบสิทธิ์ที่ล้มเหลวแม้ว่าการโทรนั้นไม่จำเป็นต้องมีการตรวจสอบสิทธิ์จึงจะสามารถโทรได้ 204 No เนื้อหาอาจเหมาะสมเช่นกัน แต่รู้สึกคลุมเครือเล็กน้อย
Cleric

4
ฉันไม่เห็นว่าสิ่งนี้จะถูกต้องได้อย่างไรเว้นแต่คุณจะใช้การตรวจสอบสิทธิ์ขั้นพื้นฐานหรือไดเจสต์ ตามส่วนที่ยกมาของข้อมูลจำเพาะ: "การตอบสนองต้องมี WWW-Authenticate" - และหากคุณอ้างถึงหัวข้อ 14.47: "กระบวนการตรวจสอบสิทธิ์การเข้าถึง HTTP อธิบายไว้ใน" HTTP Authentication: Basic and Digest Access Authentication "ซึ่งหมายความว่า สำหรับฉันแล้วว่า 401 ไม่เหมาะสมหากคุณใช้การตรวจสอบอีเมล / รหัสผ่านทั่วไป
โยนาห์

1
ฉันคิดว่านี่อาจผิดฉันได้ใช้งานไคลเอนต์ทั้งบนเว็บและมือถือและฉันสกัดกั้น 401 เพื่อเปลี่ยนเส้นทางไปยังหน้าจอเข้าสู่ระบบ แต่เมื่อมีคนอยู่ในหน้าจอการเข้าสู่ระบบและส่งข้อมูลรับรองไม่ถูกต้องการตอบกลับจะมี 401 และจะพยายามเปลี่ยนเส้นทางอีกครั้ง ควรมีรหัสสถานะที่แตกต่างกันสำหรับความพยายามที่ล้มเหลวในการตรวจสอบสิทธิ์เมื่อพยายามอย่างชัดเจน อาจเป็นคำขอที่ไม่ถูกต้องหรือแม้กระทั่งข้อผิดพลาดของเซิร์ฟเวอร์?
Japheth Ongeri - inkalimeva

27

ควรส่ง 401 เมื่อคำขอต้องการฟิลด์ส่วนหัวการอนุญาตและการอนุญาตล้มเหลว เนื่องจาก Login API ไม่จำเป็นต้องมีการอนุญาตดังนั้น 401 จึงเป็นรหัสข้อผิดพลาดที่ไม่ถูกต้องในความคิดของฉัน

ตามมาตรฐานที่นี่https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 ไม่ได้รับอนุญาต

คำขอต้องการการตรวจสอบผู้ใช้ การตอบกลับต้องมีฟิลด์ส่วนหัว WWW-Authenticate (ส่วน 14.47) ที่มีความท้าทายที่เกี่ยวข้องกับทรัพยากรที่ร้องขอ ไคลเอนต์อาจทำคำขอซ้ำด้วยฟิลด์ส่วนหัวการอนุญาตที่เหมาะสม (ส่วนที่ 14.8) หากคำขอรวมข้อมูลรับรองการให้สิทธิ์ไว้แล้วการตอบกลับ 401 แสดงว่าการอนุญาตถูกปฏิเสธสำหรับข้อมูลรับรองเหล่านั้น หากการตอบกลับ 401 มีความท้าทายเดียวกันกับการตอบกลับก่อนหน้านี้และตัวแทนผู้ใช้ได้พยายามพิสูจน์ตัวตนแล้วอย่างน้อยหนึ่งครั้งผู้ใช้ควรได้รับการนำเสนอเอนทิตีที่ได้รับในการตอบกลับเนื่องจากเอนทิตีนั้นอาจมีข้อมูลการวินิจฉัยที่เกี่ยวข้อง การตรวจสอบสิทธิ์การเข้าถึง HTTP อธิบายไว้ใน "การพิสูจน์ตัวตน HTTP: การพิสูจน์ตัวตนการเข้าถึงขั้นพื้นฐานและการย่อย" [43] *


8
ฉันเห็นด้วยกับคุณในเรื่องนี้ แต่สถานะการตอบกลับทางเลือกที่จะส่งคืออะไร? ฉันใช้งานไคลเอนต์ทั้งบนเว็บและมือถือและฉันสกัดกั้น 401 เพื่อเปลี่ยนเส้นทางไปยังหน้าจอเข้าสู่ระบบ แต่เมื่อมีคนอยู่ในหน้าจอเข้าสู่ระบบและส่งข้อมูลรับรองไม่ถูกต้องการตอบกลับก็มี 401 เช่นกันและจะพยายามเปลี่ยนเส้นทางอีกครั้ง ... คุณจะทำอย่างไร?
Japheth Ongeri - inkalimeva

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.