เซสชันทำงานใน Express.js กับ Node.js อย่างไร


96

การใช้Express.jsเซสชันนั้นง่ายมาก ฉันอยากรู้ว่าพวกเขาทำงานอย่างไร

มันเก็บคุกกี้ไว้บนไคลเอนต์หรือไม่? ถ้าเป็นเช่นนั้นฉันจะหาคุกกี้ได้ที่ไหน หากจำเป็นฉันจะถอดรหัสได้อย่างไร

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

คำตอบ:


43

ฉันไม่เคยใช้ Express.js แม้ว่าตามเอกสารของพวกเขาในหัวข้อดูเหมือนว่า:

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

  • ข้อมูลเซสชันซึ่งตรงข้ามกับเฟรมเวิร์กบางอย่าง (เช่นPlay Framework !) จะถูกเก็บไว้บนเซิร์ฟเวอร์ดังนั้นคุกกี้จึงเป็นเหมือนตัวยึดสำหรับเซสชันมากกว่าผู้ถือข้อมูลเซสชันจริง

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

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


167

ภาพรวม

Express.js ใช้คุกกี้เพื่อจัดเก็บรหัสเซสชัน (พร้อมลายเซ็นการเข้ารหัส) ในเบราว์เซอร์ของผู้ใช้จากนั้นในการร้องขอในภายหลังจะใช้ค่าของคุกกี้นั้นเพื่อดึงข้อมูลเซสชันที่เก็บไว้บนเซิร์ฟเวอร์ ที่เก็บข้อมูลฝั่งเซิร์ฟเวอร์นี้อาจเป็นที่เก็บหน่วยความจำ (ค่าเริ่มต้น) หรือที่เก็บอื่น ๆ ซึ่งใช้วิธีการที่จำเป็น (เช่นconnect-redis )

รายละเอียด

Express.js / Connect สร้างสตริงBase64 24 อักขระโดยใช้utils.uid(24)และเก็บไว้ในรูปแบบreq.sessionID. จากนั้นสตริงนี้จะถูกใช้เป็นค่าในคุกกี้

ด้านลูกค้า

คุกกี้ที่ลงชื่อจะใช้สำหรับเซสชันเสมอดังนั้นค่าคุกกี้จะมีรูปแบบดังต่อไปนี้

[sid].[signature]

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

ชื่อคุกกี้นี้คือ

connect.sid

ฝั่งเซิร์ฟเวอร์

หากตัวจัดการเกิดขึ้นหลังจากcookieParserและsessionมิดเดิลแวร์ก็จะสามารถเข้าถึงตัวแปรreq.cookiesได้ สิ่งนี้มีออบเจ็กต์ JSON ซึ่งมีคีย์คือคีย์คุกกี้และค่าต่างๆคือค่าคุกกี้ ซึ่งจะมีคีย์ที่ตั้งชื่อconnect.sidและค่าของคีย์จะเป็นตัวระบุเซสชันที่เซ็นชื่อ

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

app.get("/*", function(req, res, next) {

    if(typeof req.cookies['connect.sid'] !== 'undefined') {
        console.log(req.cookies['connect.sid']);
    }

    next(); // Call the next middleware
});

คุณต้องตรวจสอบให้แน่ใจว่าเราเตอร์ ( app.use(app.router)) รวมอยู่หลังcookieParserและsessionในส่วนกำหนดค่าของคุณ

ต่อไปนี้เป็นตัวอย่างของข้อมูลที่จัดเก็บภายในโดย Express.js / Connect

{
  "lastAccess": 1343846924959,
  "cookie": {
    "originalMaxAge": 172800000,
    "expires": "2012-08-03T18:48:45.144Z",
    "httpOnly": true,
    "path": "/"
  },
  "user": { 
    "name":"waylon",
    "status":"pro"
  }
}

userฟิลด์เป็นที่กำหนดเอง อย่างอื่นเป็นส่วนหนึ่งของการจัดการเซสชัน

ตัวอย่างมาจาก Express 2.5


1
เมื่อพิมพ์ค่าคุกกี้ด้วย console.log จะให้คุกกี้ที่เข้ารหัส (เซ็นชื่อ) ฉันจะรับข้อมูลจริงได้อย่างไร
vsync

หมายความว่าอย่างไร - "คุกกี้ของเซสชันยังคงเสี่ยงต่อการถูกขโมยและนำมาใช้ซ้ำได้หากไม่จำเป็นต้องแก้ไข [sid]"? เนื่องจาก SID ถูกสร้างขึ้นโดยด่วนเราไม่สามารถเปลี่ยนแปลงได้ใช่ไหม
Hrushikesh

2
@WebHrushi ฉันคิดถึงการโจมตีแบบคนกลาง: en.wikipedia.org/wiki/Man-in-the-middle_attack
Waylon Flinn

ใครสามารถช่วยฉันด้วยคำถามนี้stackoverflow.com/questions/21982791/…
roundrobin

ฉันจะสร้างโทเค็นสำหรับ session_id เฉพาะได้อย่างไร ??
aman verma

9

ฉันอยากรู้ว่าพวกเขาทำงานอย่างไร

ลองไปดูที่นี้คำตอบและวิกิพีเดียสิ่ง

มันเก็บคุกกี้ไว้บนไคลเอนต์หรือไม่?

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

ถ้าเป็นเช่นนั้นฉันจะหาคุกกี้ได้ที่ไหน หากจำเป็นฉันจะถอดรหัสได้อย่างไร

คุณไม่ควรยุ่งกับคุกกี้เซสชั่นทางฝั่งไคลเอ็นต์ หากคุณต้องการทำงานกับเซสชันทางฝั่งเซิร์ฟเวอร์คุณควรตรวจสอบexpress.jsที่เกี่ยวข้องและเชื่อมต่อเอกสาร


เซอร์เราคุยกันได้ไหมฉันมีข้อสงสัยเกี่ยวกับทั้งหมดนี้
Suraj Jain

1

นอกจากคำตอบที่ยอดเยี่ยมแล้วนี่คือ 2 แผนภาพที่ฉันสร้างขึ้นเพื่ออธิบายเซสชัน Express ลิงก์กับคุกกี้และที่เก็บ

  • คุกกี้ช็อกโกแลต: ช็อคโกแลต
  • คุกกี้สตรอเบอร์รี่: สตรอเบอร์รี่

ฉันขอโทษ แต่ฉันไม่เข้าใจอะไรเลยจากแผนภาพ คุณพยายามจะสื่อถึงอะไร / อยู่ในนั้น?
Rafael Sofi-zada

1
@ RafaelSofi-zada คุกกี้แต่ละชิ้นมี "รสชาติ" (หรือsessionId) ที่เป็นเอกลักษณ์ เมื่อคุกกี้สตรอเบอร์รี่ถูกนำเสนอไปยังเซิร์ฟเวอร์ (พร้อมกับคำขอ HTTP) เซิร์ฟเวอร์จะจดจำรสชาตินี้และโหลดข้อมูลที่เกี่ยวข้องจากร้านค้า: ข้อมูลของโรซี่และเติมข้อมูลreq.sessionด้วย!
abernier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.