หากแอปพลิเคชัน REST ควรไร้สถานะคุณจะจัดการเซสชันได้อย่างไร


536

ฉันต้องการคำอธิบายบางอย่าง ฉันอ่านเกี่ยวกับ REST และสร้างแอปพลิเคชัน RESTful แล้ว ตามที่วิกิพีเดีย REST ตัวเองจะถูกกำหนดให้เป็นรัฐ Representational การถ่ายโอน ฉันไม่เข้าใจgobbledeygookไร้สัญชาติทั้งหมดนี้ที่ทุกคนคอยพ่น

จากวิกิพีเดีย:

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

พวกเขากำลังบอกว่าอย่าใช้แหล่งข้อมูลระดับ / แอปพลิเคชันหรือไม่

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

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

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

อีกครั้งเพียงพยายามที่จะเข้าใจสิ่งนี้ มีคนโปรดอธิบาย


ปรับปรุง:

ฉันได้พบคำถามล้นล้นที่มีคำตอบที่ไม่ได้รับฉันไปที่นั่น: วิธีการจัดการสถานะในส่วนที่เหลือ ซึ่งบอกว่ารัฐลูกค้าที่มีความสำคัญควรทั้งหมดจะถูกโอนในทุกคำขอ .... Ugg .. ดูเหมือนว่าค่าใช้จ่ายจำนวนมาก ... ถูกต้องหรือไม่?


2
@ S.Lott: ฉันไม่คิดว่ามันทำให้เข้าใจผิดโดยเจตนา ฉันคิดว่ามันเป็นความเข้าใจผิดเนื่องจากความสับสนของคำศัพท์
เพียงความคิดเห็นที่ถูกต้องของฉัน

2
@ เพียงแค่ความคิดเห็นที่ถูกต้องของฉัน: เดาว่าน่าสนใจ ฉันไม่สามารถเชื่อสิ่งนี้ได้ด้วยตัวเองเนื่องจากเห็นได้ชัดว่า "ไร้สัญชาติ" หมายถึงโปรโตคอล REST นั้นไร้สัญชาติ ซึ่งบอกอะไรเกี่ยวกับสถานะแอปพลิเคชันพื้นฐานและอัปเดตด้วยคำขอ PUT, POST และ DELETE
S.Lott

@ S.Lott: โปรโตคอล HTTP นั้นไม่มีสถานะ จากสิ่งที่เราได้กล่าวถึงด้านล่าง REST เป็นมุมมองของวิธีการสร้างแอปของคุณในขณะที่ไม่มีเว็บเซิร์ฟเวอร์จัดการสถานะเซสชัน (ตรงข้ามกับรัฐประเภทอื่น ๆ ในสิ่งต่าง ๆ เช่น DB) ผมไม่ได้คิดว่าส่วนที่เหลือเป็นโปรโตคอล แต่มุมมองเกี่ยวกับวิธีการใช้โปรโตคอล HTTP ที่ ฉันคิดว่าพวกคุณเคลียร์แล้วว่ามันเกี่ยวกับวิธีการสร้างแอปพลิเคชันของคุณเพื่อปรับขนาดโดยให้ฝั่งลูกค้าจัดเก็บข้อมูลเซสชันลูกค้าเฉพาะทั้งหมดและทำให้การเข้าถึง URI เป็น idempotent ที่สุดเท่าที่จะทำได้ อาจจะไม่ใช่ ... :(
Zak

1
"อาจจะไม่ .. " นั่นหมายความว่าอย่างไร คุณมีคำถามใหม่หรือไม่? รู้สึกฟรีเพื่อค้นหามัน หากไม่มีอยู่ที่นี่ให้ถาม
S.Lott

มีใครอ่าน Webber, Parastatidis และ ReST ในทางปฏิบัติของ Robinson (หรือเห็นตัวอย่างของร้านอื่น) คำตอบด้านล่างนี้สมเหตุสมผล แต่แน่นอนว่าคำสั่งซื้อกาแฟในตัวอย่างของร้านกาแฟอยู่ในสถานะของลูกค้าหรือไม่? จำนวนออเดอร์จะลดลงตามจำนวนลูกค้า เส้นแบ่งระหว่างสถานะไคลเอ็นต์และทรัพยากรอยู่ที่ไหน
Rikki

คำตอบ:


340

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

จริง ๆ แล้วมีรัฐสองชนิด แอปพลิเคชันสถานะที่อาศัยอยู่บนไคลเอนต์และสถานะทรัพยากรที่อยู่บนเซิร์ฟเวอร์

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

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

หวังว่าสิ่งนี้จะช่วยแยกแยะความไร้รัฐและรัฐต่าง ๆ


4
นี่หมายความว่าทุกครั้งที่มีการส่งคำขอลูกค้าควรส่งผู้ใช้ / รหัสผ่านเพื่อตรวจสอบสิทธิ์หรือไม่ เพราะฉันเดาว่าจะจัดเก็บเซสชันแม้ว่าจะอยู่ในฐานข้อมูล no-sql db ที่ใช้ร่วมกันระหว่างเซิร์ฟเวอร์ทั้งหมดไม่ใช่ไร้สัญชาติหรือเป็นอย่างไร
Carlos Navarro Astiasarán

1
@ CarlosNavarroAstiasaránมีเทคนิคหลากหลายสำหรับการจัดการการพิสูจน์ตัวตนแบบไร้รัฐ ตัวอย่างเช่น Google JWT
geoidesic

1
@geoidesic: "เนื่องจากโทเค็นเว็บ JSON ไร้สัญชาติจึงไม่มีวิธีที่จะทำให้เป็นโมฆะโดยไม่ต้องเก็บสถานะเซิร์ฟเวอร์ดังนั้นจึงเป็นการเอาชนะความได้เปรียบของโทเค็นไร้สัญชาติ" WIkipedia
ulatekh

@ulatekh นั่นคือการบิดเบือนความจริงของสิ่งที่คุณสามารถทำได้กับโทเค็น มันค่อนข้างง่ายในการจัดเก็บ ID ที่ได้รับการอนุมัติพร้อมกับโทเค็นและยอมรับโทเค็นที่มี ID ที่ได้รับการอนุมัติเป็นสิทธิ์เท่านั้น ไร้สัญชาติไม่ได้หมายความว่าคุณไม่สามารถทำอะไรในฐานข้อมูล เป็นหลักคุณเก็บ ID ในฐานข้อมูลที่ต้องตรงกับ ID เดียวกันในโทเค็น หากต้องการยกเลิกโทเค็นคุณจะต้องลบ ID ออกจากฐานข้อมูล ไม่มีการจดจำสถานะในบริการของตัวเอง หรือดียิ่งกว่านั้นคุณจัดเก็บรหัสลงนามกับผู้ใช้ในฐานข้อมูลและยกเลิกคีย์
Andrew T Finnell

@AndrewTFinnell: หากคุณต้องจัดเก็บ ID ที่ได้รับอนุมัติบนเซิร์ฟเวอร์มันจะต้องถูกเก็บไว้ในเซิร์ฟเวอร์ที่มีศักยภาพทั้งหมดที่สามารถดำเนินการเข้าสู่ระบบ REST ซึ่งอาจเกี่ยวข้องกับสถานะของเซิร์ฟเวอร์จำนวนมากในสถาปัตยกรรมเว็บเซิร์ฟเวอร์ขนานกันอย่างหนาแน่น
ulatekh

491

คำอธิบายพื้นฐานคือ:

ไม่มีสถานะเซสชันไคลเอ็นต์บนเซิร์ฟเวอร์

เมื่อไม่มีสถานะหมายความว่าเซิร์ฟเวอร์ไม่ได้เก็บสถานะใด ๆ เกี่ยวกับเซสชันไคลเอ็นต์ไว้ที่ฝั่งเซิร์ฟเวอร์

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

นั่นไม่ได้ขัดขวางบริการอื่น ๆ ที่เว็บเซิร์ฟเวอร์พูดถึงจากการดูแลรักษาสถานะเกี่ยวกับวัตถุทางธุรกิจเช่นตะกร้าสินค้าไม่เพียงเกี่ยวกับสถานะแอปพลิเคชัน / เซสชันปัจจุบันของลูกค้า

ของลูกค้ารัฐแอพลิเคชันไม่ควรเก็บไว้ในเซิร์ฟเวอร์ แต่ผ่านรอบจากลูกค้าถึงสถานที่ที่ทุกคนที่ตอบสนองความต้องการมัน

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

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

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

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

มีหลักการใช้งานขั้นพื้นฐานบางอย่าง:

หลักการเหล่านี้ไม่ใช่การใช้งานวิธีที่คุณปฏิบัติตามหลักการเหล่านี้อาจแตกต่างกันไป

โดยสรุปหลักการสำคัญห้าประการคือ:

  1. ให้ ID ทุกสิ่ง
  2. เชื่อมโยงสิ่งต่าง ๆ เข้าด้วยกัน
  3. ใช้วิธีการมาตรฐาน
  4. ทรัพยากรที่มีตัวแทนหลายรายการ
  5. สื่อสารอย่างไร้สัญชาติ

ไม่มีอะไรที่เกี่ยวกับการตรวจสอบหรือการอนุมัติในส่วนที่เหลือเป็นวิทยานิพนธ์

เพราะไม่มีอะไรแตกต่างจากการตรวจสอบคำขอที่สงบจากที่ไม่ได้ การรับรองความถูกต้องไม่เกี่ยวข้องกับการสนทนาสงบ

การอธิบายวิธีสร้างแอปพลิเคชั่นไร้สัญชาติสำหรับความต้องการเฉพาะของคุณนั้นกว้างเกินไปสำหรับ StackOverflow

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

ความคิดเห็นขอความช่วยเหลือ / ข้อมูลเกี่ยวกับการนี้จะ / ควรจะถูกจัดเป็น ไม่จำเป็น


22
ดูเหมือนว่าเป็นคำแถลงที่ชัดเจนว่าเป็นหนทางเดียวในการขยายจำนวนผู้ใช้หลายล้านคน ทำไมเซสชันฝั่งเซิร์ฟเวอร์ไม่สามารถเป็นเพียงบริการอื่นได้
Zak

27
@Zak: เนื่องจากเซสชันนับล้านเป็นเซสชันนับล้าน จุดคือเพื่อหลีกเลี่ยงค่าใช้จ่ายของการจัดการเซสชันทั้งหมดนี้
S.Lott

91
มันไม่ใช่ความกล้าหาญที่มันเป็นประสบการณ์

21
ไม่มีคำตอบของฉันแสดงถึงวิธีการแก้ปัญหาตามการเข้าถึงฐานข้อมูลในทุกคำขอหากคุณคิดว่าเป็นเช่นนั้นมันเป็นความล้มเหลวในส่วนของคุณที่จะเข้าใจการตรวจสอบและการอนุญาตในระดับนั้น การรับรองความถูกต้องสามารถอยู่ในสถานะคุณคิดว่า facebook จะ "เข้าถึงฐานข้อมูล" ในทุกคำขอของ REST API หรือไม่? หรือ Google สำหรับเรื่องนั้น? คำใบ้: ไม่

6
ดังนั้นถ้าฉันเก็บสถานะผู้ใช้ในแคชแบบกระจาย memcache และเว็บเซิร์ฟเวอร์ของฉันตอนนี้ไม่จำเป็นต้องเก็บสถานะใด ๆ แต่ไปและรับสถานะจาก memcache ฉันสามารถพิจารณาแอปพลิเคชันนี้ไร้รัฐได้หรือไม่?
Jaskey

76

พวกเขากำลังบอกว่าอย่าใช้แหล่งข้อมูลระดับ / แอปพลิเคชันหรือไม่

ไม่พวกเขาไม่ได้พูดแบบนั้นเล็กน้อย

พวกเขากำลังพูดว่าอย่ากำหนด "เซสชั่น" อย่าเข้าสู่ระบบ อย่าออกจากระบบ ระบุข้อมูลประจำตัวพร้อมคำขอ แต่ละคำขอยืนอยู่คนเดียว

คุณยังมีที่เก็บข้อมูล คุณยังคงมีการตรวจสอบและการอนุญาต คุณไม่ต้องเสียเวลาในการสร้างเซสชันและรักษาสถานะเซสชัน

ประเด็นคือแต่ละคำร้องขอ (a) ยืนอยู่คนเดียวอย่างสมบูรณ์และ (b) สามารถทำไร่ไถนาเล็กน้อยไปยังฟาร์มเซิร์ฟเวอร์ขนาดยักษ์คู่ขนานโดยไม่มีงานจริงใด ๆ Apache หรือ Squid สามารถส่งคำร้องขอ RESTful รอบ ๆ สุ่มสี่สุ่มห้าและสำเร็จ

ถ้าฉันมีคิวของข้อความและผู้ใช้ของฉันต้องการอ่านข้อความ แต่เมื่อเขาอ่านพวกเขาต้องการบล็อกข้อความของผู้ส่งบางข้อความที่ผ่านมาในช่วงเวลาของเซสชันของเขา?

หากผู้ใช้ต้องการตัวกรองให้ระบุตัวกรองสำหรับแต่ละคำขอ

มันจะไม่สมเหตุสมผลหรือไม่ที่จะให้เซิร์ฟเวอร์ส่งข้อความ (หรือรหัสข้อความ) ที่ผู้ใช้ไม่ได้ถูกบล็อก?

ใช่. จัดเตรียมตัวกรองในคำร้องขอ RESTful URI

ฉันต้องส่งรายชื่อผู้ส่งข้อความทั้งหมดเพื่อปิดกั้นทุกครั้งที่ขอรายการข้อความใหม่หรือไม่

ใช่. "รายชื่อผู้ส่งข้อความที่จะบล็อก" นี้มีขนาดเท่าใด รายการย่อของ PK หรือไม่

คำขอ GET อาจมีขนาดใหญ่มาก หากจำเป็นคุณสามารถลองคำขอ POST ได้แม้ว่าจะดูเหมือนเป็นข้อความค้นหา


28
"ไม่ต้องเข้าสู่ระบบห้ามออกจากระบบให้ข้อมูลประจำตัวพร้อมคำขอ" ฉันมักจะเห็นคำตอบเช่นนี้ในคำถามเกี่ยวกับวิธีการคงสถานะไร้สัญชาติใน REST API โดยไม่มีรายละเอียดใด ๆ ว่าควรเก็บข้อมูลประจำตัวเหล่านั้นไว้ที่ใด / อย่างไร แน่นอนว่าเราไม่ควรเก็บชื่อผู้ใช้และรหัสผ่านไว้ในที่จัดเก็บในตัวเครื่อง!
BeniRose

2
@BeniRose เราไม่สามารถเก็บโทเค็นใน localstorage และใช้โทเค็นนั้นในคำขอที่จะระบุผู้ใช้โดยไม่ซ้ำกันได้หรือไม่
Nikhil Sahu

1
Localstorage มีข้อกังวลด้านความปลอดภัยมากมายจากสิ่งที่ฉันเข้าใจ แต่ยังมีข้อกังวลอื่น ๆ อีกมากมายเกี่ยวกับเซสชันฝั่งไคลเอ็นต์เช่นโทเค็นที่ทำให้ใช้งานไม่ได้การออกจากระบบของผู้ใช้เป็นต้น
BeniRose

3
คุณใช้ JWT ที่มีลายเซ็นการตรวจสอบลายเซ็นนั้นรวดเร็วเพื่อให้คุณสามารถตรวจสอบความถูกต้องของสถานะนั้น
Archimedes Trajano

36

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

ทันทีที่คุณมีความรับผิดชอบเล็กน้อยบนเซิร์ฟเวอร์เพื่อจัดการข้อมูลบางอย่างที่เกี่ยวข้องกับการโต้ตอบของลูกค้าเฉพาะภาระที่สามารถเติบโตได้อย่างรวดเร็วเพื่อใช้เซิร์ฟเวอร์

มันเป็นการแลกเปลี่ยน


32

มุมมองประวัติของการจัดการสถานะแอปพลิเคชันผู้ใช้

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

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

คำขอส่วนหัวของ HTML5 และ XML นั้นมีความคิดมาตรฐานในการจัดเก็บข้อมูลที่ซับซ้อนรวมถึงสถานะของแอปพลิเคชันในแบบมาตรฐานบนฝั่งไคลเอ็นต์ (เช่นเบราว์เซอร์) โดยไม่ต้องหันกลับไปกลับมาระหว่างเซิร์ฟเวอร์

การใช้งานทั่วไปของบริการ REST

โดยทั่วไปจะเรียกใช้บริการ REST เมื่อมีธุรกรรมที่ต้องดำเนินการหรือหากจำเป็นต้องดึงข้อมูล

เซอร์วิส REST นั้นถูกเรียกใช้โดยแอ็พพลิเคชันฝั่งไคลเอ็นต์ไม่ใช่ผู้ใช้ปลายทางโดยตรง

ตรวจสอบสิทธิ์

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

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

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

ดึงคำขอ

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

สคริปต์ธุรกรรม

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

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

สิ่งนี้ทำผ่านการPOSTร้องขอโดยปกติ แต่คนอื่น ๆ เช่นPUTสามารถใช้

จำนวนมากของตัวอย่างที่วางแผนของส่วนที่เหลือ (ตัวผมเองทำอย่างนี้) พยายามที่จะทำตามมากของสิ่งที่ได้รับการกำหนดไว้ในโปรโตคอล HTTP, หลังจากผ่านที่ฉันตัดสินใจที่จะเป็นในทางปฏิบัติมากขึ้นและทิ้งมันไปGET และ POST เท่านั้น POSTวิธีการไม่ได้มีการดำเนินการรูปแบบ POST-เปลี่ยนเส้นทางการ GET-

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

การลงคะแนนเลือกตั้ง

แม้ว่า REST สามารถใช้สำหรับการสำรวจได้เช่นกัน แต่ฉันจะไม่แนะนำเว้นแต่คุณจะต้องใช้เพราะความเข้ากันได้ของเบราว์เซอร์ เพื่อที่ฉันจะใช้ WebSockets ซึ่งฉันได้ออกแบบสัญญา APIด้วยเช่นกัน อีกทางเลือกหนึ่งสำหรับเบราว์เซอร์รุ่นเก่าคือ CometD


27

ส่วนที่เหลือเป็นนามธรรมมาก ช่วยให้มีตัวอย่างที่ดีเรียบง่ายและใช้งานจริงได้

ยกตัวอย่างแอพโซเชียลมีเดียสำคัญ ๆ ทั้งหมดเช่น Tumblr, Instagram, Facebook และ Twitter พวกเขาทุกคนมีมุมมองแบบเลื่อนตลอดเวลาซึ่งคุณเลื่อนไปทางไกลยิ่งมีเนื้อหามากเท่าไหร่คุณก็ยิ่งเห็นย้อนเวลามากขึ้น อย่างไรก็ตามเราทุกคนมีประสบการณ์ในช่วงเวลาที่คุณสูญเสียตำแหน่งที่คุณเลื่อนไปและแอพรีเซ็ตคุณกลับไปด้านบน เช่นถ้าคุณออกจากแอพเมื่อคุณเปิดใหม่คุณจะกลับมาที่ด้านบนอีกครั้ง

สาเหตุที่เป็นเพราะเซิร์ฟเวอร์ไม่ได้เก็บสถานะเซสชันของคุณ น่าเศร้าตำแหน่งการเลื่อนของคุณถูกเก็บไว้ใน RAM บนไคลเอนต์

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

คุณไม่มีเซสชันการเข้าสู่ระบบบนเซิร์ฟเวอร์เพราะพวกเขาปฏิบัติตาม REST


ตอนนี้ตัวอย่างข้างต้นไม่เกี่ยวข้องกับเว็บเบราว์เซอร์เลย แต่ในตอนท้ายแอพกำลังสื่อสารผ่าน HTTPS กับเซิร์ฟเวอร์โฮสต์ ประเด็นของฉันคือ REST ไม่ต้องเกี่ยวข้องกับคุกกี้และเบราว์เซอร์ ฯลฯ มีวิธีการต่างๆในการจัดเก็บสถานะเซสชันฝั่งไคลเอ็นต์

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

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

ไม่สามารถใช้ที่อยู่ IP ของพวกเขาได้เพราะหลายคนอาจใช้ที่อยู่เดียวกันนั้นบนเราเตอร์ที่ใช้ร่วมกัน งั้นเป็นไง?

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

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


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


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


13

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

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

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

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

การเก็บข้อมูลเซสชันที่ละเอียดอ่อนบางอย่างไว้บนเซิร์ฟเวอร์ควรเป็นวิธีที่ถูกต้อง คุณไม่สามารถเชื่อถือลูกค้าเพื่อเก็บตะกร้าสินค้าของตนได้ (ตัวอย่างเช่น) มีฟิลด์ชื่อ "isFreeGift" ข้อมูลดังกล่าวควรถูกเก็บไว้บนเซิร์ฟเวอร์

ลิงก์วิดีโอที่Santanu Dey ให้ไว้ในคำตอบของเขานั้นมีประโยชน์ ดูมันถ้าคุณยังไม่ได้

เพียงหมายเหตุด้าน: ดูเหมือนว่าคำตอบทั้งหมดที่ให้ไว้ดูเหมือนจะไม่สนใจข้อเท็จจริงที่ว่าการดำเนินการบางอย่างอาจทำให้เกิดการโหลดจำนวนมากบนเซิร์ฟเวอร์ สิ่งนี้มีความเกี่ยวข้องในแง่ของการใช้พลังงานการใช้ฮาร์ดแวร์และค่าใช้จ่าย (สำหรับเซิร์ฟเวอร์ที่ให้เช่าโดยรอบ CPU) นักพัฒนาที่ดีไม่ควรขี้เกียจในการเพิ่มประสิทธิภาพแอปพลิเคชันแม้ว่าการดำเนินการสามารถทำได้อย่างรวดเร็วบน CPU ที่ทันสมัยบนเซิร์ฟเวอร์ที่ให้เช่าบางแห่งซึ่งพวกเขาไม่ต้องจ่ายค่าไฟฟ้าและค่าบำรุงรักษา

คำถามนี้มีอายุสองสามปีแล้วฉันหวังว่าคำตอบของฉันจะยังคงมีประโยชน์


4
โดยทั่วไปฉันเห็นด้วยกับความรู้สึกนี้ แต่มีแนวโน้มล่าสุดที่จะอ้างว่าแม้แต่ตัวระบุเซสชันไม่ควรเก็บไว้ในเซิร์ฟเวอร์ ฉันยังไม่ทราบว่าโซลูชันทางเลือกคืออะไร JWT ได้รับการขนานนามอย่างดี แต่มาพร้อมกับ gotchas จำนวนหนึ่ง: cryto.net/~joepie91/blog/2016/06/19/…
BeniRose

11

ไร้สัญชาติหมายถึงสถานะของบริการไม่คงอยู่ระหว่างคำร้องขอและการตอบสนองที่ตามมา แต่ละคำขอมีข้อมูลรับรองผู้ใช้ของตนเองและได้รับการตรวจสอบสิทธิ์เป็นรายบุคคล แต่ใน stateful แต่ละคำขอเป็นที่รู้จักจากการร้องขอล่วงหน้าใด ๆ คำขอแบบ stateful ทั้งหมดเป็นแบบ session-oriented เช่นแต่ละคำขอจำเป็นต้องทราบและเก็บการเปลี่ยนแปลงที่ทำในคำขอก่อนหน้านี้

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

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

HTTP ไม่มีสถานะ แต่เรายังสามารถรักษาเซสชันในแอปพลิเคชัน java ของเราโดยใช้กลไกการติดตามเซสชันที่แตกต่างกัน

ใช่เราสามารถรักษาเซสชันในเว็บเซอร์ว่าเป็น REST หรือ SOAP สามารถนำไปใช้งานได้โดยใช้ห้องสมุดบุคคลที่สามหรือคุณสามารถนำไปใช้กับเรา

นำมาจากhttp://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap


11

ไม่มีช้อน.

อย่าคิดว่าไร้รัฐเช่น "ส่งสิ่งของทั้งหมดของคุณไปยังเซิร์ฟเวอร์ซ้ำแล้วซ้ำอีก" ไม่มีทาง. จะมีสถานะอยู่เสมอ - ฐานข้อมูลเองเป็นสถานะหลังจากทั้งหมดคุณเป็นผู้ใช้ที่ลงทะเบียนดังนั้นข้อมูลชุดฝั่งไคลเอ็นต์จะไม่ถูกต้องหากไม่มีฝั่งเซิร์ฟเวอร์ ในทางเทคนิคแล้วคุณไม่เคยไร้สัญชาติอย่างแท้จริง

คำในการอภิปรายทุกครั้งที่เข้าสู่ระบบ

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

ลดรอยเท้า

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

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

ดังนั้นคุณกำลังพูดให้เก็บเซสชั่นให้น้อยที่สุด?

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

ทำอย่างไรจึงจะถูกต้องแล้ว?

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

คิดและตัดสินใจอย่าปล่อยให้แนวโน้มการออกแบบคิดเพื่อคุณ


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

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

@dkellner ฉันไม่เข้าใจส่วนนั้น: "เซิร์ฟเวอร์ต้องรู้ว่าอย่างน้อยถ้ามีคนลงชื่อเข้าใช้หรือไม่ (และถ้าคุณรบกวนฐานข้อมูลทุกครั้งที่คุณต้องตัดสินใจในเรื่องนี้คุณต้องตัดสินใจอีกครั้ง)" สมมติว่าคุณเก็บข้อมูลเซสชันในฐานข้อมูลด้วย PHP ทำไมการสืบค้น DB สำหรับการเข้าสู่ระบบที่ไม่ดี (ถึงขนาดเป็นคำที่หนักแน่น) เนื่องจากจะมีการร้องขอ DB ที่ตามมาจำนวนมากเพื่อรับข้อมูลผู้ใช้ที่สมบูรณ์และข้อมูลอื่น ๆ โดยยึดตามรหัสเซสชัน PHP กล่าวอีกนัยหนึ่งแบบสอบถามฐานข้อมูลจะหลีกเลี่ยงไม่ว่าในกรณีใด ๆ นอกจากนี้หากคุณไม่ได้รับรหัสเซสชัน PHP คุณรู้ว่าผู้ใช้ไม่ได้รับการรับรองความถูกต้องไม่จำเป็นต้องค้นหา
user2923322

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

5

ลองดูที่การนำเสนอนี้

http://youtu.be/MRxTP-rQ-S8

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


1
โปรดอ่านฉันจะเขียนคำตอบที่ดีได้อย่างไร ก่อนที่จะพยายามตอบคำถามเพิ่มเติม

3

ความแตกต่างที่สำคัญระหว่าง stateless vs Stateful คือข้อมูลที่ถูกส่งกลับไปยังเซิร์ฟเวอร์ทุกครั้ง ในกรณีที่ไร้สัญชาติลูกค้าจะต้องให้ข้อมูลทั้งหมดดังนั้นพารามิเตอร์จำนวนมากอาจต้องผ่านในแต่ละคำขอ ใน Stateful, cliet ส่งผ่านพารามิเตอร์เหล่านั้นเพียงครั้งเดียวและพวกเขาจะดูแลโดยเซิร์ฟเวอร์จนกว่าจะแก้ไขโดยไคลเอนต์อีกครั้ง

IMO, API ควรไร้สถานะซึ่งทำให้สามารถขยายขนาดได้อย่างรวดเร็ว


2

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

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


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

1

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

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

หาก RESTful API ต้องการชื่อผู้ใช้และรหัสผ่านเพื่อเปลี่ยนชื่อผู้ใช้และรหัสผ่านแม้ว่าใครบางคนจะแอบอ้างเป็นผู้ใช้โดยใช้รหัสเซสชันแฮ็กเกอร์จะไม่สามารถล็อคผู้ใช้จริงได้

session-id สามารถสร้างขึ้นได้โดยการล็อคแบบทางเดียว (การเข้ารหัส) ของสิ่งที่ระบุผู้ใช้และเพิ่มเวลาใน id ของเซสชันซึ่งจะทำให้สามารถกำหนดเวลาหมดอายุของเซสชันได้

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


เรื่องนี้ทำให้รู้สึก
mestarted

0

แนวคิดทั้งหมดต่างกัน ... คุณไม่จำเป็นต้องจัดการเซสชันหากคุณพยายามใช้โปรโตคอล RESTFul ในกรณีนั้นมันจะดีกว่าที่จะทำขั้นตอนการตรวจสอบในทุกคำขอ (ในขณะที่มีค่าใช้จ่ายเพิ่มเติมในแง่ของประสิทธิภาพ - รหัสผ่านการแฮชจะเป็นตัวอย่างที่ดีไม่ใช่เรื่องใหญ่ ... ) หากคุณใช้เซสชันคุณจะกระจายโหลดไปยังหลาย ๆ เซิร์ฟเวอร์ได้อย่างไร ฉันพนันได้เลยว่า RESTFul protocol นั้นมีจุดประสงค์เพื่อกำจัดเซสชันใด ๆ - คุณไม่ต้องการมันจริงๆ ... นั่นเป็นเหตุผลที่มันถูกเรียกว่า "ไร้สัญชาติ" เซสชั่นจะต้องเฉพาะเมื่อคุณไม่สามารถเก็บสิ่งอื่นที่ไม่ใช่คุกกี้บนฝั่งไคลเอ็นต์หลังจากทำคำขอซ้ำ (ใช้เบราว์เซอร์ที่สนับสนุน Javascript / HTML5 ที่ไม่ใช่เก่าเป็นตัวอย่าง) ในกรณีของไคลเอนต์ RESTFul "เต็มรูปแบบ" โดยปกติจะปลอดภัยในการจัดเก็บbase64(login:password) บนฝั่งไคลเอ็นต์ (ในหน่วยความจำ) จนกระทั่งการโหลดแอปพลิเคชันยังคงอยู่ - แอปพลิเคชันจะใช้ในการเข้าถึงโฮสต์เท่านั้นและคุกกี้ไม่สามารถถูกบุกรุกโดยสคริปต์ของบุคคลที่สาม ...

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


3
อะไรคือa client side (in memory) วิธีที่ปลอดภัยที่จะบันทึกbase64(login:password)ในฝั่งไคลเอ็นต์?
RN Kushwaha

1
ไม่มีสิ่งใดถูกกำหนดให้เป็น "ปลอดภัยอย่างสมบูรณ์" อย่างไรก็ตามคุณสามารถพิจารณาใช้ OAuth2 ที่ให้ความปลอดภัยที่ดีกว่าการบันทึกสตริง base64 สำหรับคำขอ API (การตรวจสอบขั้นพื้นฐาน) หากคุณใช้งานการตรวจสอบขั้นพื้นฐานคุณสามารถใช้ HTTPS เพื่อความปลอดภัยที่ดีขึ้น
felixwcf

3
RN Kushwaha นี่เป็นคำถามที่ไม่มีใครอยากตอบเมื่อพวกเขาบอกให้คุณหยุดการจัดเก็บเซสชันบนเซิร์ฟเวอร์และเก็บไว้ในไคลเอนต์
BeniRose

0

REST เป็นไร้สัญชาติและไม่รักษาสถานะใด ๆ ระหว่างคำขอ คุกกี้ / ส่วนหัวไคลเอนต์ถูกตั้งค่าให้รักษาสถานะผู้ใช้เช่นการรับรองความถูกต้อง สมมติว่าชื่อผู้ใช้ / รหัสผ่านของลูกค้าได้รับการตรวจสอบโดยกลไกการตรวจสอบความถูกต้องของส่วนที่สาม - การจัดระดับ OTP ระดับ 2 เป็นต้นเมื่อผู้ใช้ได้รับการรับรองความถูกต้อง - ส่วนหัว / คุกกี้มาถึงจุดสิ้นสุดบริการ . ตอนนี้ข้อมูลบางอย่างของผู้ใช้เช่น IP จะถูกเก็บไว้ในแคชและหลังจากนั้นหากคำขอมาจาก Ip เดียวกัน (ที่อยู่ mac) สำหรับทรัพยากรที่มีในรายการผู้ใช้จะได้รับอนุญาต และแคชจะถูกเก็บไว้เป็นบางครั้งซึ่งจะทำให้ใช้งานไม่ได้เมื่อหมดเวลา ดังนั้นแคชสามารถใช้หรือรายการ DB สามารถใช้เพื่อยืนยันข้อมูล b / w การร้องขอ


0

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

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

สิ่งนี้สามารถรักษาหรือติดตามสถานะของผู้ใช้ในแอปพลิเคชัน

หวังว่านี่จะช่วยได้!

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