เซสชันคืออะไร พวกเขาทำงานอย่างไร


332

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

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

แต่ตามเพียงแค่ ID เซสชั่นฉันจะทราบชื่อผู้ใช้ของฉันได้อย่างไรในระหว่างการสำรวจผ่านเว็บไซต์ครั้งต่อไป มันเก็บข้อมูลบนเซิร์ฟเวอร์เป็น Dict ที่สำคัญจะเป็นหมายเลขเซสชั่นและรายละเอียดเช่นusername, emailฯลฯ เป็นค่า?

ฉันสับสนมากที่นี่ ต้องการความช่วยเหลือ.


9
“ มันเก็บข้อมูลบนเซิร์ฟเวอร์เป็น dict โดยที่คีย์จะเป็นรหัสเซสชันและรายละเอียดเช่นชื่อผู้ใช้อีเมล ฯลฯ เป็นค่าหรือไม่” ...ใช่. 'dict' อาจเป็นฐานข้อมูลเชิงสัมพันธ์ แต่โดยพื้นฐานแล้วมันทำงานอย่างไร
bobince

14
ฉันต้องการที่จะเข้าใจเซสชันของเว็บด้วยตอนนี้ฉันก็เข้าใจแล้ว ฉันลงเอยด้วยการเขียน wiki ของฉันเองหากมีความช่วยเหลือใด ๆ : machinesaredigging.com/2013/10/29/how-does-a-web-session-work
eloone

ในกรณีที่คุณไม่ทราบ: การจัดเก็บรหัสผ่านทางฝั่งไคลเอ็นต์ไม่ปลอดภัยแม้ว่ารหัสผ่านจะถูกแฮช (จริง ๆ แล้วมันไม่ได้สร้างความแตกต่าง Cracker สามารถป้อนรหัสผ่านที่ถูกแฮชได้โดยตรงด้วยการสร้างคุกกี้ปลอม) เป็นวิธีที่ดีกว่าในการจัดเก็บสถานะการเข้าสู่ระบบ
cytsunny

1
ฉันเขียนเองโดยใช้รายละเอียดระดับโปรโตคอล - bitspedia.com/2012/05/…
Asif Shahzad

คำตอบ:


400

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

คุกกี้หรือพารามิเตอร์ URL (เช่นเช่นhttp://example.com/myPage?asd=lol&boo=no ) เป็นวิธีที่เหมาะสมในการขนส่งข้อมูลระหว่าง 2 คำขอขึ้นไป อย่างไรก็ตามข้อมูลเหล่านี้ไม่ดีในกรณีที่คุณไม่ต้องการให้ข้อมูลอ่าน / แก้ไขได้ในฝั่งไคลเอ็นต์

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

แน่นอนว่ายังมีแง่มุมอื่น ๆ ที่ต้องพิจารณาเช่นคุณไม่ต้องการให้คนอื่นแย่งชิงเซสชันอื่นคุณต้องการให้เซสชันไม่คงอยู่ตลอดไป แต่จะหมดอายุและอื่น ๆ

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


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

5
@MattHarrison คุณจะถอดรหัสข้อมูลโดยไม่ต้อง "จดจำอะไร" ฝั่งเซิร์ฟเวอร์ได้อย่างไร ฉันพยายามขยายหัวข้อนี้ในคำตอบของฉัน แต่อย่างใด
Luke404

2
@MattHarrison โปรดทราบว่าการจัดเก็บข้อมูลจำนวนมากด้านผู้ใช้จะเพิ่มปริมาณการใช้งานของคุณ
nitsas

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

2
@ user137717 ใช่ว่าเป็นไปได้ถ้าคุณอนุญาตให้เข้าถึงเซสชั่นอย่างแท้จริง "ทุกคนที่แสดง ID เซสชั่นที่ถูกต้อง" มีข้อ จำกัด หลายประการที่คุณสามารถทำได้หนึ่งในวิธีที่ง่ายที่สุดและบ่อยที่สุดคือการจัดเก็บ IP ไคลเอ็นต์ในเซสชัน: หากไคลเอนต์จาก ip อื่นแสดงรหัสเซสชันเดียวกันกับที่คุณทำเครื่องหมายว่าเป็นการปลอมแปลงและลบเซสชัน
ลุ

110

คำอธิบายง่ายๆโดยการเปรียบเทียบ

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

ธนาคารนี้เป็นธนาคารประเภทที่ตลก - เพื่อประโยชน์ในการโต้แย้งนี่คือสิ่งที่ทำงาน:

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

แต่นักเล่าเรื่องจะบอกคุณต่างจากคนอื่นอย่างไร?

หมอดูไม่สามารถมองเห็นหรือจำคุณได้ง่ายจำไว้เพราะแสงนั้นดับแล้ว จะเป็นอย่างไรถ้าพนักงานรับเงินของคุณถอนเงิน 10,000 เหรียญให้คนอื่น - คนผิดล่ะ! มันสำคัญอย่างยิ่งที่พนักงานรับฝากจะรับรู้ว่าคุณเป็นคนที่ทำการถอนเงินเพื่อที่คุณจะได้รับเงิน (หรือทรัพยากร) ที่คุณขอ

สารละลาย:

เมื่อคุณปรากฏตัวต่อผู้บอกเป็นครั้งแรกเขาหรือเธอจะบอกคุณบางอย่างเป็นความลับ:

"เมื่อใดก็ตามที่คุณกำลังพูดกับฉัน" พนักงานบอกว่า "คุณควรระบุตัวคุณเองว่าเป็น GNASHEU329 - อย่างที่ฉันรู้ว่าเป็นคุณ"

ไม่มีใครรู้รหัสลับ

ตัวอย่างของวิธีถอนเงินออก:

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

พนักงานถามฉัน: "คุณเป็นใคร ??!"

"ฉันเองนายจอร์จแบ๊งส์!"

"พิสูจน์สิ!"

จากนั้นฉันก็บอกรหัสผ่านแก่พวกเขา: GNASHEU329

"แน่นอนนายธนาคาร!"

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

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

คำอธิบายผ่านรูปภาพ:

การบรรยายอธิบายผ่านรูปภาพ


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

@wmock การหักหลังเซสชันเป็นปัญหาอย่างแน่นอน: ลองดูสิ! owasp.org/index.php/Session_hijacking_attack
BKSpurgeon

2
ตัวอย่างที่น่ารัก !! มันจะถูกแบ่งปันกับจิตใจที่กระตือรือร้นที่กำลังมองหาการเรียนรู้!
วิกเตอร์

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

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

39

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

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

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

หวังว่าจะช่วย


ฉันรู้บนเซิร์ฟเวอร์ IIS ที่ฉันใช้ฉันสามารถรับชื่อผู้ใช้จากส่วนหัวของ USER_NAME แต่นั่นอาจเป็นเฉพาะ IIS
Tim Rourke

ผู้อ้างอิงหมายถึงอะไรที่นี่?
Gab 是好人

@Gab 是好人ผู้อ้างอิงมักจะหมายถึงสตริงโดยพลการที่ลูกค้าส่งในส่วนหัวคำขอ HTTP "อ้างอิง" มันควรมี URL ของทรัพยากรที่คุณรู้จักแนะนำลูกค้าไปยังทรัพยากรปัจจุบัน
ลุ

ขอบคุณมันควรดังนั้นไม่จำเป็น ดังนั้นฉันคิดว่าผู้คนมักใช้หัวข้อนี้กับซีแมนทิกส์ที่แตกต่างจากข้อเสนอแนะใน RFC ใช่ไหม
Gab 是好人

ครั้งแรกที่คุณเขียนแล้วLike cookies, this usually doesn't get sent in the URL anymore Session variables are like cookies - they're name-value pairs sent along with a request for a pageเกิดอะไรขึ้นกันแน่? มันจะถูกส่งในครั้งต่อไปที่คุณทำการร้องขอใด ๆ ?
KPMG

19

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

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

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


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

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

เช่นเดียวกับคำถามข้างต้นก็จะเป็นประโยชน์ถ้าคุณตอบสนอง
Suraj Jain

4

คิดว่า HTTP เป็นบุคคล (A) ที่มีการสูญเสียหน่วยความจำระยะสั้นและลืมทุกคนทันทีที่บุคคลนั้นมองไม่เห็น

ตอนนี้เพื่อจดจำคนอื่น A ถ่ายภาพของบุคคลนั้นและเก็บมันไว้ รูปของแต่ละคนมีหมายเลขประจำตัว เมื่อบุคคลนั้นปรากฏตัวอีกครั้งบุคคลนั้นจะบอกว่าเป็นหมายเลข ID ต่อ A และ A ค้นหารูปภาพของตนตามหมายเลข ID และ voila !! A รู้ว่าใครคือบุคคลนั้น

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

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