คุณช่วยฉันเข้าใจสิ่งนี้ได้ไหม “ ข้อผิดพลาด REST ทั่วไป: เซสชันไม่เกี่ยวข้อง”


159

คำเตือน: ฉันใหม่สำหรับโรงเรียนแห่งความคิดและฉันพยายามที่จะปิดใจของฉัน

ดังนั้นฉันกำลังอ่านหน้านี้ข้อผิดพลาด REST ทั่วไปและฉันพบว่าฉันงงงวยอย่างสมบูรณ์โดยส่วนที่เกี่ยวกับการประชุมที่ไม่เกี่ยวข้อง นี่คือสิ่งที่หน้าพูดว่า:

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

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

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


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

คำตอบ:


79

หากต้องการสงบเงียบคำขอ HTTP แต่ละครั้งควรมีข้อมูลเพียงพอด้วยตัวเองเพื่อให้ผู้รับดำเนินการให้สอดคล้องกับลักษณะไร้สัญชาติของ HTTP

ตกลงฉันได้รับการตรวจสอบความถูกต้องของ HTTP นั้นจะทำโดยอัตโนมัติในทุกข้อความ

ใช่ชื่อผู้ใช้และรหัสผ่านจะถูกส่งทุกคำขอ วิธีการทั่วไปที่จะทำเพื่อให้มีการตรวจสอบการเข้าถึงพื้นฐานและย่อยตรวจสอบการเข้าถึง และใช่ผู้ดักฟังสามารถดักจับข้อมูลรับรองของผู้ใช้ หนึ่งจึงจะเข้ารหัสข้อมูลทั้งหมดที่ส่งและรับใช้Transport Layer Security (TLS)

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

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

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


5
คำตอบนี้ไม่สมเหตุสมผลสำหรับฉัน ครั้งแรกมันบอกว่ามันก็โอเคที่จะส่งผ่านการเข้าสู่ระบบและรหัสผ่านในแต่ละครั้งและยังอีกครั้งซึ่งทำให้รู้สึก จากนั้นแนะนำให้กลับสู่สถานะการเข้าสู่ระบบของลูกค้าที่ประสบความสำเร็จในรูปแบบของโทเค็น ถ้าจำเป็นโทเค็นสามารถเข้ารหัสเวลาของการสร้าง เราได้รับอนุญาตให้ส่งคืนข้อมูลกลับไปยังลูกค้าอย่างแน่นอน ดังนั้นข้อเสนอแนะนี้ดูเหมือนจะดีสำหรับฉัน คำตอบบอกว่ามันไม่ดีเพราะ "มันมีสถานะ" แต่ไม่ใช่แนวคิดของ "ST" ใน "REST" ที่สถานะนั้นสามารถถ่ายโอนระหว่างไคลเอ็นต์และเซิร์ฟเวอร์ได้หรือไม่

33

ไม่ใช่เรื่องแปลกที่บริการ REST จะต้องมีการตรวจสอบสิทธิ์สำหรับทุกคำขอ HTTP ตัวอย่างเช่น Amazon S3 ต้องการให้ทุกคำขอมีลายเซ็นต์ที่ได้รับจากข้อมูลรับรองผู้ใช้การร้องขอที่แน่นอนเพื่อดำเนินการและเวลาปัจจุบัน ลายเซ็นนี้ง่ายต่อการคำนวณทางฝั่งไคลเอ็นต์สามารถตรวจสอบได้อย่างรวดเร็วจากเซิร์ฟเวอร์และมีการ จำกัด การใช้งานสำหรับผู้โจมตีที่ขัดขวางมัน (เนื่องจากขึ้นอยู่กับเวลาปัจจุบัน)


3
+1 คุณสามารถโปรดซับซ้อนใน: เป็นของใช้ที่ จำกัด ในการโจมตีที่ขัดขวางมัน (ตั้งแต่มันขึ้นอยู่กับเวลาปัจจุบัน) ความ ? คุณไม่พูดเกี่ยวกับคุกกี้ที่มีชื่อผู้ใช้และรหัสผ่านที่เข้ารหัสหรือไม่? เช่นนั้นไหม (IMHO)
Royi Namir

2
@RoyiNamir: ฉันไม่ได้พูดถึงคุกกี้ ลายเซ็นที่ใช้โดย S3 เป็นพารามิเตอร์สำหรับคำขอ HTTP แต่ไม่ใช่คุกกี้จะถูกคำนวณใหม่สำหรับทุกคำขอ
Greg Hewgill

ดังนั้นหากฉันต้องการบันทึกข้อมูลเกี่ยวกับผู้ใช้ฉันจะบันทึกได้ที่ไหน ใน db? ฉันไม่ต้องการที่จะไปขอ DB แต่ละครั้งและยังฉันต้องการที่จะใช้ส่วนที่เหลือ .... คุณช่วยได้ไหม
Royi Namir

@RoyiNamir: ถ้าคุณมีคำถามเกี่ยวกับวิธีการบรรลุเป้าหมายบางโปรดถามคำถามใหม่ ฉันไม่สามารถตอบคำถามเพิ่มเติมได้ที่นี่ในความคิดเห็น
Greg Hewgill

10

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

ในกรณีของคุณฉันว่าใช่นี่คือ RESTy แต่ลองหลีกเลี่ยงการใช้เซสชัน php ดั้งเดิมใน REST API ของคุณและเริ่มสร้างโทเค็นที่แฮชของคุณเองซึ่งหมดอายุในเวลาที่กำหนด!


1
ขอบคุณ. เหตุใดจึงควรหลีกเลี่ยงเซสชัน php ดั้งเดิมและใช้โทเค็นแฮชของตัวเองแทน
Matthew

ไม่ใช่เหตุผลที่ยอดเยี่ยมที่ฉันพูดเพียงเพื่อความปลอดภัยมากขึ้นและการควบคุมมากขึ้น
EvilThinker

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

8

ไม่พลาดไม่ได้ ClientLoginของ Google ทำงานในลักษณะนี้โดยมีข้อยกเว้นที่น่าสังเกตว่าลูกค้าได้รับคำสั่งให้ไปที่ "/ เซสชัน" โดยใช้การตอบกลับ HTTP 401 แต่นี่ไม่ได้สร้างเซสชั่นมันสร้างวิธีให้ลูกค้า (ชั่วคราว) ตรวจสอบตัวเองโดยไม่ต้องผ่านข้อมูลประจำตัวในที่ชัดเจนและสำหรับเซิร์ฟเวอร์ในการควบคุมความถูกต้องของข้อมูลประจำตัวชั่วคราวเหล่านี้ตามที่เห็นสมควร


11
@ unwgiven3 ตราบใดที่โทเค็นที่ส่งคืนถูกใช้เพื่อรับรองความถูกต้องของผู้ใช้เท่านั้นและเซิร์ฟเวอร์ไม่ได้ใช้เพื่อเชื่อมโยงผู้ใช้กับสถานะอื่นที่เก็บไว้บนเซิร์ฟเวอร์จากนั้นฉันเห็นว่าไม่มีการละเมิดข้อ จำกัด REST
Darrel Miller

4
@ unwgiven3 โทเค็นที่ส่งคืนโดยเซิร์ฟเวอร์คือผลการพิสูจน์ผู้ใช้คือผู้ที่พวกเขาบอกว่าพวกเขาเป็น ดังนั้นแทนที่จะร้องขอแต่ละครั้งรวมถึงชื่อผู้ใช้และรหัสผ่านแต่ละคำขอจะมีโทเค็นซึ่งสร้างขึ้นในลักษณะที่เซิร์ฟเวอร์สามารถมั่นใจในความถูกต้องได้
Darrel Miller

1
@ unwgiven3, Darrel ถูกต้อง โทเค็นสะท้อนกลับจะต้องถูกส่งโดยลูกค้าในทุกคำขอ HTTP เช่นเดียวกับในขั้นพื้นฐานการตรวจสอบสิทธิ์ย่อยจนกว่าโทเค็นหมดอายุ เมื่อสิ่งนั้นเกิดขึ้นลูกค้าสามารถทำซ้ำการเข้าสู่ระบบเลือกถามผู้ใช้สำหรับข้อมูลประจำตัวหรืออะไรก็ตาม ฉันสามารถอธิบายคำตอบได้อย่างละเอียดถ้าคุณต้องการ แก้ไข: (และขอขอบคุณที่ติดตามคำตอบของคำถามเก่า ๆ !)
mogsie

1
ไม่มีปัญหา mogsie น่าสนใจเสมอที่จะพูดถึงสิ่งต่าง ๆ เหล่านี้ :-) ฉันคิดว่าฉันเห็นว่าคุณจะไปทางไหนโชคไม่ดีที่ฉันไม่เข้าใจเกี่ยวกับการพิสูจน์ตัวจริงของการรับรู้แบบย่อย (เข้าใจได้ง่าย) เข้าใจว่าโทเค็นจะถูกส่งกลับคำขอ HTTP แต่ละครั้ง แต่ดูเหมือนว่าจะมีรายละเอียดการใช้งาน) อย่างไรก็ตามตอนนี้ฉันเห็นแล้วว่าทำไมวิธีนี้จึงไม่ละเมิดหลักการ REST ขอบคุณสำหรับคำตอบ!
Rob

6
@ unwgiven3 สิ่งนี้อาจช่วยได้: โทเค็นเป็นข้อมูลที่ลงนามแล้ว ดังนั้นมันจึงมีอยู่ในตัวเอง เซิร์ฟเวอร์สามารถตรวจสอบโทเค็นได้โดยไม่ต้องตรวจสอบสถานะที่เก็บไว้ก่อนหน้านี้ ดังนั้นจึงเป็นเพียงสถานะที่เก็บไว้ในไคลเอนต์และโอนไปมา
Iravanchi

5

ตกลงฉันได้รับการตรวจสอบความถูกต้องของ HTTP นั้นจะทำโดยอัตโนมัติในทุกข้อความ

"การอนุญาต:" ส่วนหัว HTTP ส่งโดยลูกค้า มีทั้งแบบพื้นฐาน (ข้อความธรรมดา) หรือสรุปย่อ

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

แนวคิดทั้งหมดของเซสชันคือการทำให้แอปพลิเคชันstatefulใช้โปรโตคอลไร้สัญชาติ (HTTP) และไคลเอนต์โง่ (เว็บเบราว์เซอร์) โดยรักษาสถานะไว้ที่ฝั่งเซิร์ฟเวอร์ หนึ่งในหลักการส่วนที่เหลือเป็น"ทรัพยากรที่ทุกคนเป็นแอดเดรสที่ไม่ซ้ำกันโดยใช้ไวยากรณ์สากลสำหรับการใช้งานในการเชื่อมโยงหลายมิติ" ตัวแปรเซสชันเป็นสิ่งที่ไม่สามารถเข้าถึงได้ผ่าน URI แอปพลิเคชั่น RESTful อย่างแท้จริงจะรักษาสถานะไว้ที่ฝั่งไคลเอ็นต์ส่งตัวแปรที่จำเป็นทั้งหมดโดย HTTP โดยเฉพาะอย่างยิ่งใน URI

ตัวอย่าง: ค้นหาด้วยการแบ่งหน้า คุณมี URL ในรูปแบบ

http://server/search/urlencoded-search-terms/page_num

มีหลายอย่างที่เหมือนกันกับ URL ที่คั่นหน้าได้


4
ข้อมูลการรับรองความถูกต้องไม่สามารถเข้าถึงได้ผ่าน URI เช่นกัน - ทุกคนกำลังพูดถึงการส่งข้อมูลรับรองความถูกต้องซึ่งเป็นส่วนหนึ่งของส่วนหัวคำขอ แตกต่างจากการรวมโทเค็นเซสชันกับคำขออย่างไร ฉันไม่ได้บอกว่าใช้โทเค็นเซสชันใน URI แต่ในข้อมูลที่ส่งผ่านในคำขอ
Rob

การพิสูจน์ตัวตนจะเกิดขึ้นหากคุณได้รับอนุญาตให้ดำเนินการนั้นและในแอปพลิเคชัน RESTful จะไม่ส่งผลต่อผลลัพธ์ของมัน
vartec

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

3
ไม่โทเค็นของเซสชันเป็นหมายเลขอ้างอิงสำหรับบันทึกสถานะบนเซิร์ฟเวอร์ นั่นไม่ใช่แค่สงบ สำหรับ Not Notized ฉันไม่เห็นว่าเป็นผลลัพธ์ ฉันควรพิจารณาว่าเป็นข้อยกเว้น (เช่นลอง / จับ)
vartec

ยุติธรรมเพียงพอ vartec - เหมาะสมแล้ว ขอบคุณสำหรับการติดตาม!
Rob

3

ฉันคิดว่าข้อเสนอแนะของคุณคือตกลงถ้าคุณต้องการควบคุมเวลาชีวิตของลูกค้าเซสชั่น ฉันคิดว่าสถาปัตยกรรม RESTful สนับสนุนให้คุณพัฒนาแอพพลิเคชั่นไร้สัญชาติ ดังที่ @ 2pence เขียนว่า"คำขอ HTTP แต่ละรายการควรมีข้อมูลเพียงพอสำหรับตัวผู้รับเพื่อดำเนินการให้สอดคล้องกับลักษณะไร้สัญชาติของ HTTP"โดยสมบูรณ์

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

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