การจัดการการหมดเวลาของเซสชันผู้ใช้ในแอป SaaS - พูดคุยถึงวิธีการหลายวิธี


11

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

นี่เป็นปัญหาที่พบบ่อยและฉันแน่ใจว่ามันมีวิธีปฏิบัติที่ดีที่สุดที่กำหนดไว้

พื้นหลัง

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

  2. เซสชันเซิร์ฟเวอร์เก็บวัตถุผู้ใช้เท่านั้นโดยใช้คุกกี้เซสชันที่ไม่ถาวร

  3. เซสชันหมดอายุบนเซิร์ฟเวอร์หลังจาก X ชั่วโมง

  4. บางสิ่งถูกโหลดระหว่างการล็อกอินเท่านั้น

ปัญหา

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

การแก้ปัญหาที่เป็นไปได้

นี่คือวิธีแก้ปัญหาบางอย่างที่ฉันมีในใจอยากจะได้ยินหากมีคนอื่นและถ้ามีอะไรผิดปกติกับพวกเขา

1. อย่าล็อกผู้ใช้ออก

  • อย่างไร? อาจเก็บเซสชันที่ยาวนานเก็บคุกกี้ถาวรหรือ ping javaScript "keep alive"
  • ข้อดี : ผู้ใช้ไม่จำเป็นต้องกังวลอะไรเลยแก้ไขปัญหาให้พวกเขา
  • ข้อด้อย : ไม่เป็นไปตามมาตรฐาน PCI ไม่ปลอดภัยและต้องการการเปลี่ยนแปลงการพัฒนาเช่นสิ่งที่โหลดไปยังเซสชันเฉพาะเมื่อเข้าสู่ระบบของผู้ใช้จำเป็นต้องย้ายไปที่รูปแบบย่อย pub (ฟังการเปลี่ยนแปลงเหตุการณ์) หรือหมดเวลาแคช

2. การจัดเก็บในท้องถิ่น

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

3. บันทึกอัตโนมัติ

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

  • อย่างไร? ใช้เฟรมเวิร์ก MV ** (Backbone.js / Knockout.js / Ember.js / Angular.js ฯลฯ ) เพื่อเชื่อมโยงโมเดลและยืนยันการเปลี่ยนแปลง
  • ข้อดี : ดูเหมือนว่าโซลูชันที่สะอาดเซสชันจะแอ็คทีฟตราบใดที่ผู้ใช้แอ็คทีฟไม่มีการทำงานด้านไคลเอ็นต์โดยไม่คงอยู่
  • ข้อด้อย : ผู้ใช้แอ็คชั่นคนสุดท้ายกำลังทำหลังจากหมดเวลาเซสชันไปแล้ว

4. ล็อกผู้ใช้ออกหลังจากเซสชันหมดอายุ

สิ่งนี้สามารถมีหลายวิธี

  1. ถามเซิร์ฟเวอร์ "หมดอายุเซสชัน" - นี่เป็นบิตของแมวที่ 22 / Schrodinger ที่จับเป็นเพียงคำถามไปยังเซิร์ฟเวอร์ขยายเซสชัน (เริ่มหมดเวลา)

    • อย่างไร? อาจมีเซิร์ฟเวอร์ที่รองรับคำถามดังกล่าว (ฉันไม่ทราบ แต่ฉันมาจาก Java land) หรือหนึ่งสามารถเก็บ ID ของเซสชันและเวลาเข้าถึงล่าสุดด้วยตนเองและถามเซิร์ฟเวอร์โดยผ่านเซสชัน ID เป็นพารามิเตอร์แทนที่จะเป็นคุกกี้ฉันไม่แน่ใจว่าสิ่งนี้จะเป็นไปได้หรือไม่ แต่มันฟังดูอันตรายการออกแบบที่ไม่ปลอดภัยและไม่ดีหน้าใด ๆ ทั้งสิ้นล็อกยังคงมีอยู่เมื่อลงชื่อเข้าใช้
    • ข้อดี : หากมีการสนับสนุนดั้งเดิมในเซิร์ฟเวอร์ดูเหมือนคำถามที่ชัดเจนและถูกกฎหมาย (ถามว่าผู้ใช้ X ยังมีเซสชันหรือไม่โดยไม่ต้องต่ออายุหากทำ)
    • ข้อด้อย : หากเซิร์ฟเวอร์ไม่รองรับ (และอีกครั้งฉันไม่รู้ว่าเซิร์ฟเวอร์หรือกรอบการทำงานใดมีฟังก์ชั่นนี้) การแก้ปัญหามีความเสี่ยงด้านความปลอดภัยอย่างมาก
  2. วิธีแก้ปัญหาหนึ่งที่ฉันได้ยินมาคือมีเซสชั่นสั้น ๆ ที่ฝั่งเซิร์ฟเวอร์และ ping ฝั่งไคลเอ็นต์ที่ยังมีชีวิตอยู่ซึ่งมีจำนวน ping สูงสุด

    • อย่างไร? เซสชันสั้น ๆ บนเซิร์ฟเวอร์ไคลเอนต์ส่ง Ping ทุก sessionTimeOut / 2 มีการลองใหม่สูงสุดของ Y
    • จุดเด่น : ชนิดของการแก้ไขปัญหารวดเร็วและสกปรก
    • ข้อด้อย : รู้สึกเหมือนแฮ็คจัดการเซสชันต่ออายุตัวเองแทนที่จะปล่อยให้เซิร์ฟเวอร์ทำ
  3. จับเวลาฝั่งไคลเอ็นต์

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

    • ข้อดี : แก้ไขปัญหา

    • ข้อด้อย : ไม่สามารถนึกถึงสิ่งใดได้นอกจากความจำเป็นในการตรวจสอบให้แน่ใจว่าการซิงค์ทำงาน

คำถาม

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


ฉันใช้เชิงมุมและ django กับ Deliciouspie ดังนั้นนี่คือความคิดของฉันจากมุมมองนั้น: 4.1: คลาสการรับรองความถูกต้องที่ใช้สำหรับทรัพยากรทั้งหมดของคุณสามารถตรวจสอบและเปรียบเทียบความแตกต่างของเวลาระหว่างนี้กับค่าของฟิลด์ แบบ 401 คือเวลามากกว่าเวลาที่กำหนด 200 nowเป็นอย่างอื่นและการปรับปรุงสนามสุดท้ายของการเข้าถึงด้วย 4.2 ฟังดูเป็นวิธีที่ยอดเยี่ยมในการฆ่าเซิร์ฟเวอร์ของคุณและเพิ่มค่าใช้จ่าย 4.3 สำหรับ Android เมื่อกลับไปที่หน้าจอหลักฉันค่อนข้างแน่ใจว่ากระบวนการหยุดชั่วคราวและอาจรบกวนการจับเวลาของลูกค้าของคุณ
airtonix

คำตอบ:


5

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

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

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


2

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

อย่างไร? เซสชั่นสั้น ๆ บนเซิร์ฟเวอร์ไคลเอนต์ส่ง Ping ทุกครั้งที่เวลา / 2, มีการลองใหม่สูงสุดของ Y ข้อดี: ชนิดของการแก้ไขปัญหารวดเร็วและสกปรกจุดด้อย: รู้สึกเหมือนแฮ็คจัดการเซสชั่นต่ออายุด้วยตัวคุณเองแทนที่จะปล่อยให้เซิร์ฟเวอร์ทำ

นี่คือความคิดของฉันทางออกที่ดีที่สุด ทำไมคุณถึงคิดว่ามันเป็น "แฮ็คที่สกปรก"?

มันทำให้สิ่งที่ต้องทำ ในขณะที่ผู้ใช้ทำงานกับโปรแกรมเซสชันจะยังคงเปิดอยู่

หลังจากที่ผู้ใช้หยุดทำงานกับโปรแกรมเซสชันจะถูกปิด

ง่ายพอที่จะดำเนินการ

ถ้าฉันเข้าใจคำถามที่ถูกต้อง


บางครั้งการแฮ็กสกปรกเป็นทางแก้ปัญหาที่ดีที่สุด :) ขอบคุณ คุณเข้าใจคำถามถูกต้องแล้ว
Eran Medan

2

จริงๆแล้วฉันกำลังสร้างแอปพลิเคชันที่เกี่ยวข้องกับเรื่องนี้

ฉันเริ่มต้นด้วยการสร้างบริการสงบโดยใช้ Django, Guradian และ Tastypie มันรับรองความถูกต้องโดยใช้ APIKEY เท่านั้นการอนุญาตให้วัตถุถูกจัดการโดย Guardian

แอป django มีเพียงหนึ่งมุมมองเทมเพลต urlconf ที่โหลด base.html ซึ่งคือ ...

ในฝั่งไคลเอ็นต์ฉันสร้างแอปพลิเคชันโดยใช้ Angular

การพิสูจน์ตัวตนจะมี http-auth-interceptor ที่คอยรับฟังการตอบกลับ 401 ครั้ง

เมื่อรับ 401 มันจะบัฟเฟอร์คำขอออกและปิดเหตุการณ์ "จำเป็นต้องเข้าสู่ระบบ" สิ่งนี้อาจเกิดขึ้นหลายครั้ง

ฉันมีป๊อปอัป modal ที่มีรูปแบบการเข้าสู่ระบบที่นำเสนอเมื่อได้ยินเหตุการณ์ "จำเป็นต้องเข้าสู่ระบบ" และมันทำการเข้าสู่ระบบที่ส่งกลับทรัพยากรผู้ใช้ (บันเดิล JSON) ซึ่งจะมี APIKEY

คำขอที่บัฟเฟอร์ทั้งหมดซึ่งก่อนหน้านี้ส่งผลให้เกิดการตอบสนอง 401 จะถูกเล่นซ้ำด้วย APIKEY ในตอนนี้รวมอยู่ในส่วนหัว HTTP การอนุญาต

ฉันใช้บริการ / โรงงานเชิงมุมอีกอันเพื่อจัดการข้อมูล json ของ localstorage และนั่นคือสิ่งที่ฉันใช้เก็บชื่อผู้ใช้และ apikey

ปริศนาชิ้นเดียวที่เหลือเพื่อแก้ไขคือวิธีการรักษาความปลอดภัยข้อมูลนั้นและวิธีการบังคับใช้การหมดเวลาของข้อมูลนั้น

อาจใช้การตรวจสอบเวลาประทับจากคำขอ http ที่ถูกต้องครั้งสุดท้าย


จากการติดตามเรื่องนี้ฉันได้พิจารณาเปรียบเทียบการตรวจสอบรับรองความถูกต้อง Deliciouspie แต่ละรายการต่อไปนี้: current_time> user.lastlogin_time + settings.SESSION_TIMEOUT จากนั้นส่งคืน 401 หากเป็นจริง การพิสูจน์ตัวตนที่ถูกต้องแต่ละครั้งจะอัพเดต user.lastlogin_time เป็น current_time
airtonix

มันค่อนข้างดีและฉันคิดยังไงเกี่ยวกับการจัดการมัน
oligofren

1

ในกรณีของฉันฉันใช้สิ่งที่คล้ายกับ 4.1 หลังจากที่ผู้ใช้เข้าสู่ระบบคำขอ AJAX json เชิงมุมที่มีน้ำหนักเบามากเกิดขึ้นกับ REST API ตามช่วงเวลาที่กำหนดไว้กับเซิร์ฟเวอร์ เนื่องจากข้อกำหนดด้านความปลอดภัย UI ที่เป็นกรรมสิทธิ์คาดว่าเซิร์ฟเวอร์จะรักษาเซสชันสำหรับผู้ใช้ซึ่งเก็บข้อมูลที่ได้รับการป้องกันเทมเพลตข้อมูลและอื่น ๆ ที่ด้านเซิร์ฟเวอร์ นี่ยังคงเป็นวิธีที่ฉันต้องการจากมุมมองด้านความปลอดภัย เมื่อจัดการกับข้อมูลที่ละเอียดอ่อน (ไม่ใช่แค่รหัสผ่านที่ถูกแฮชและเช่นนั้น) IMO จะเก็บข้อมูลฝั่งไคลเอ็นต์ไว้ใน Local Storage และอื่น ๆ มีความเสี่ยงมากกว่าฝั่งเซิร์ฟเวอร์ บุคคลที่สามใช้ API เดียวกันเมื่อสื่อสารกับระบบ แต่ต้องส่งข้อมูลรับรองความถูกต้องในทุกคำขอ

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

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

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

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

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