มีคำถามมากมายถามที่นี่และดูเหมือนว่าแม้ว่าคำถามจะถูกถามในบริบทของ Node และ passport.js คำถามจริงเกี่ยวกับเวิร์กโฟลว์มากกว่าวิธีการทำเช่นนี้ด้วยเทคโนโลยีเฉพาะ
ลองใช้การตั้งค่าตัวอย่าง @ Keith ปรับเปลี่ยนบิตเพื่อเพิ่มความปลอดภัย:
- เว็บเซิร์ฟเวอร์ที่
https://example.com
ให้บริการแอปไคลเอนต์ Javascript หน้าเดียว
- บริการเว็บสงบที่
https://example.com/api
ให้การสนับสนุนเซิร์ฟเวอร์แอปลูกค้ามากมาย
- เซิร์ฟเวอร์ใช้งานในโหนดและ passport.js
- เซิร์ฟเวอร์มีฐานข้อมูล (ชนิดใดก็ได้) พร้อมตาราง "ผู้ใช้"
- เสนอชื่อผู้ใช้ / รหัสผ่านและ Facebook Connect เป็นตัวเลือกการตรวจสอบสิทธิ์
- ไคลเอนต์ที่หลากหลายทำการร้องขอ REST
https://example.com/api
- อาจจะมีลูกค้าอื่น ๆ (ปพลิเคชันโทรศัพท์เป็นต้น) ที่ใช้บริการเว็บที่แต่ไม่ทราบเกี่ยวกับเว็บเซิร์ฟเวอร์ที่
https://example.com/api
https://example.com
โปรดทราบว่าฉันใช้ HTTP ที่ปลอดภัย นี่เป็นความคิดของฉันที่ต้องมีสำหรับบริการใด ๆ ที่เปิดให้บริการเนื่องจากข้อมูลที่ละเอียดอ่อนเช่นรหัสผ่านและโทเค็นการอนุญาตกำลังผ่านระหว่างไคลเอนต์และเซิร์ฟเวอร์
การตรวจสอบชื่อผู้ใช้ / รหัสผ่าน
ลองดูว่าการรับรองความถูกต้องแบบเก่าทำงานอย่างไรก่อน
- ผู้ใช้เชื่อมต่อกับ
https://example.com
- เซิร์ฟเวอร์ให้บริการแอปพลิเคชัน Javascript ที่มีรูปแบบหลากหลายซึ่งแสดงผลหน้าเริ่มต้น บางคนในหน้านี้มีแบบฟอร์มเข้าสู่ระบบ
- ส่วนต่างๆของแอพพลิเคชั่นหน้าเดียวนี้ยังไม่ได้มีการเติมข้อมูลเนื่องจากผู้ใช้ไม่ได้เข้าสู่ระบบส่วนเหล่านี้ทั้งหมดมีฟังเหตุการณ์ในเหตุการณ์ "เข้าสู่ระบบ" ทั้งหมดนี้คือสิ่งที่ฝั่งไคลเอ็นต์เซิร์ฟเวอร์ไม่ทราบเหตุการณ์เหล่านี้
- ผู้ใช้เข้าสู่ระบบ / รหัสผ่านของเขา / เธอและกดปุ่มส่งซึ่งทริกเกอร์จัดการจาวาสคริปต์เพื่อบันทึกชื่อผู้ใช้และรหัสผ่านในตัวแปรฝั่งไคลเอ็นต์ จากนั้นตัวจัดการนี้จะเรียกเหตุการณ์ "เข้าสู่ระบบ" อีกครั้งนี้เป็นทุกการกระทำด้านลูกค้า, ข้อมูลประจำตัวที่ไม่ได้ถูกส่งไปยังเซิร์ฟเวอร์ ๆ
- ผู้ฟังเหตุการณ์ "เข้าสู่ระบบ" ถูกเรียกใช้ ตอนนี้แต่ละรายการจำเป็นต้องส่งคำขออย่างน้อยหนึ่งคำขอไปยัง RESTful API ที่
https://example.com/api
เพื่อรับข้อมูลเฉพาะของผู้ใช้เพื่อแสดงผลในหน้า ทุกคำขอเดียวที่พวกเขาส่งไปยังบริการเว็บจะมีชื่อผู้ใช้และรหัสผ่านซึ่งอาจอยู่ในรูปแบบของการรับรองความถูกต้องHTTP พื้นฐานเนื่องจากบริการที่สงบไม่ได้รับอนุญาตให้รักษาสถานะไคลเอนต์จากคำขอหนึ่งไปยังอีก เนื่องจากบริการทางเว็บนั้นอยู่บน HTTP ที่ปลอดภัยรหัสผ่านจึงถูกเข้ารหัสอย่างปลอดภัยในระหว่างการขนส่ง
- บริการเว็บที่
https://example.com/api
ได้รับคำขอจำนวนมากแต่ละคำขอมีข้อมูลการตรวจสอบสิทธิ์ ชื่อผู้ใช้และรหัสผ่านในการร้องขอแต่ละครั้งจะถูกตรวจสอบกับฐานข้อมูลผู้ใช้และหากพบว่าถูกต้องจะมีการเรียกใช้ฟังก์ชันที่ร้องขอและข้อมูลจะถูกส่งคืนไปยังไคลเอ็นต์ในรูปแบบ JSON หากชื่อผู้ใช้และรหัสผ่านไม่ตรงกับข้อผิดพลาดจะถูกส่งไปยังลูกค้าในรูปแบบของรหัสข้อผิดพลาด 401 HTTP
- แทนที่จะบังคับให้ลูกค้าส่งชื่อผู้ใช้และรหัสผ่านทุกคำขอคุณสามารถใช้ฟังก์ชัน "get_access_token" ในบริการ RESTful ของคุณซึ่งใช้ชื่อผู้ใช้และรหัสผ่านและตอบกลับด้วยโทเค็นซึ่งเป็นแฮชการเข้ารหัสลับบางอย่างที่ไม่เหมือนใคร วันที่ที่เกี่ยวข้องกับมัน โทเค็นเหล่านี้จะถูกเก็บไว้ในฐานข้อมูลกับผู้ใช้แต่ละคน จากนั้นไคลเอ็นต์จะส่งโทเค็นการเข้าถึงในคำขอถัดไป โทเค็นการเข้าถึงจะถูกตรวจสอบกับฐานข้อมูลแทนชื่อผู้ใช้และรหัสผ่าน
- แอปพลิเคชันไคลเอนต์ที่ไม่ใช่เบราว์เซอร์เช่นแอพโทรศัพท์ทำเช่นเดียวกับด้านบนพวกเขาขอให้ผู้ใช้ป้อนข้อมูลประจำตัวของเขา / เธอแล้วส่งพวกเขา (หรือโทเค็นการเข้าถึงที่สร้างขึ้นจากพวกเขา) ทุกคำขอไปยังบริการเว็บ
จุดที่สำคัญใช้เวลาห่างจากตัวอย่างนี้คือบริการเว็บสงบต้องตรวจสอบทุกครั้งที่มีการร้องขอ
เลเยอร์ความปลอดภัยเพิ่มเติมในสถานการณ์นี้จะเพิ่มการอนุญาตแอปพลิเคชันไคลเอนต์นอกเหนือจากการรับรองความถูกต้องของผู้ใช้ ตัวอย่างเช่นหากคุณมีเว็บไคลเอ็นต์แอป iOS และ Android ทั้งหมดที่ใช้บริการเว็บคุณอาจต้องการให้เซิร์ฟเวอร์รู้ว่าลูกค้าทั้งสามคนของคำขอที่ได้รับคืออะไร สิ่งนี้สามารถเปิดใช้บริการเว็บของคุณเพื่อ จำกัด ฟังก์ชั่นบางอย่างให้กับลูกค้าเฉพาะ สำหรับสิ่งนี้คุณสามารถใช้คีย์และความลับ API ได้ดูคำตอบนี้สำหรับแนวคิดบางประการ
การรับรองความถูกต้องของ Facebook
เวิร์กโฟลว์ด้านบนไม่ทำงานสำหรับการเชื่อมต่อ Facebook เนื่องจากการเข้าสู่ระบบผ่าน Facebook มีบุคคลที่สาม Facebook เอง ขั้นตอนการเข้าสู่ระบบกำหนดให้ผู้ใช้ต้องเปลี่ยนเส้นทางไปยังเว็บไซต์ของ Facebook ที่ป้อนข้อมูลรับรองภายนอกการควบคุมของเรา
ดังนั้นเรามาดูกันว่าสิ่งต่าง ๆ เปลี่ยนแปลง:
- ผู้ใช้เชื่อมต่อกับ
https://example.com
- เซิร์ฟเวอร์ให้บริการแอปพลิเคชัน Javascript ที่มีรูปแบบหลากหลายซึ่งแสดงผลหน้าเริ่มต้น บางคนในหน้านี้มีแบบฟอร์มเข้าสู่ระบบที่มีปุ่ม "เข้าสู่ระบบด้วย Facebook"
- ผู้ใช้คลิกที่ปุ่ม "เข้าสู่ระบบด้วย Facebook" ซึ่งเป็นเพียงการเชื่อมโยงว่าการเปลี่ยนเส้นทางไป
https://example.com/auth/facebook
(ตัวอย่าง)
https://example.com/auth/facebook
เส้นทางจะถูกจัดการโดย passport.js (ดูเอกสารประกอบ )
- ผู้ใช้ทุกคนเห็นว่าหน้านั้นเปลี่ยนไปและตอนนี้พวกเขาอยู่ในหน้าโฮสต์ของ Facebook ซึ่งพวกเขาจำเป็นต้องลงชื่อเข้าใช้และอนุญาตแอปพลิเคชันเว็บของเรา สิ่งนี้อยู่นอกเหนือการควบคุมของเราอย่างสมบูรณ์
- บันทึกของผู้ใช้ใน Facebook และให้สิทธิ์ในการประยุกต์ใช้ของเราดังนั้น Facebook ตอนนี้เปลี่ยนเส้นทางกลับไปยัง URL เรียกกลับที่เรากำหนดค่าในการตั้งค่า passport.js ซึ่งต่อไปนี้ตัวอย่างในเอกสารเป็น
https://example.com/auth/facebook/callback
- ตัวจัดการ passport.js สำหรับ
https://example.com/auth/facebook/callback
เส้นทางจะเรียกใช้ฟังก์ชันการเรียกกลับที่ได้รับโทเค็นการเข้าถึง Facebook และข้อมูลผู้ใช้บางส่วนจาก Facebook รวมถึงที่อยู่อีเมลของผู้ใช้
- ด้วยอีเมลเราสามารถค้นหาผู้ใช้ในฐานข้อมูลของเราและจัดเก็บโทเค็นการเข้าถึง Facebook ด้วย
- สิ่งสุดท้ายที่คุณทำในการติดต่อกลับของ Facebook คือการเปลี่ยนเส้นทางกลับไปที่แอปพลิเคชันไคลเอนต์ที่หลากหลาย แต่คราวนี้เราต้องส่งชื่อผู้ใช้และโทเค็นการเข้าถึงไปยังลูกค้าเพื่อให้สามารถใช้งานได้ สามารถทำได้หลายวิธี ตัวอย่างเช่นตัวแปร Javascript สามารถเพิ่มไปยังหน้าผ่านเครื่องมือแม่แบบฝั่งเซิร์ฟเวอร์มิฉะนั้นคุกกี้สามารถส่งคืนพร้อมข้อมูลนี้ (ขอบคุณ @RyanKimber สำหรับการชี้ปัญหาด้านความปลอดภัยเมื่อส่งข้อมูลนี้ใน URL ตามที่ฉันแนะนำไว้ในตอนแรก)
- ดังนั้นตอนนี้เราเริ่มแอปหน้าเดียวอีกครั้ง แต่ลูกค้ามีชื่อผู้ใช้และโทเค็นการเข้าถึง
- แอปพลิเคชันไคลเอนต์สามารถเรียกใช้เหตุการณ์ "เข้าสู่ระบบ" ได้ทันทีและให้ส่วนต่าง ๆ ของแอปพลิเคชันร้องขอข้อมูลที่ต้องการจากบริการเว็บ
- คำขอทั้งหมดที่ส่งไป
https://example.com/api
จะรวมโทเค็นการเข้าถึง Facebook สำหรับการรับรองความถูกต้องหรือโทเค็นการเข้าถึงของแอปพลิเคชันที่สร้างขึ้นจากโทเค็นของ Facebook ผ่านฟังก์ชั่น "get_access_token" ใน REST API
- แอปที่ไม่ใช่เบราว์เซอร์ทำให้มันยากขึ้นเล็กน้อยที่นี่เนื่องจาก OAuth ต้องการเว็บเบราว์เซอร์สำหรับการลงชื่อเข้าใช้ในการลงชื่อเข้าใช้จากโทรศัพท์หรือแอพเดสก์ท็อปคุณจะต้องเริ่มเบราว์เซอร์เพื่อเปลี่ยนเส้นทางไปยัง Facebook ต้องการวิธีที่เบราว์เซอร์จะส่งโทเค็นการเข้าถึง Facebook กลับไปยังแอปพลิเคชันผ่านกลไกบางอย่าง
ฉันหวังว่าสิ่งนี้จะตอบคำถามส่วนใหญ่ได้ แน่นอนคุณสามารถแทนที่ Facebook ด้วย Twitter, Google หรือบริการตรวจสอบความถูกต้องตาม OAuth อื่น ๆ
ฉันสนใจที่จะรู้ว่ามีใครบางคนมีวิธีที่ง่ายกว่าในการจัดการกับเรื่องนี้
passport-facebook
สำหรับ หลังจากที่คุณได้รับการทำงานขั้นตอนต่อไปคือการเริ่มทำความเข้าใจวิธีการทำงานของ Passport และวิธีการเก็บหนังสือรับรอง เชื่อมต่อกับ Restify ( ดูที่นี่สำหรับเวอร์ชันที่อัปเดตของเวอร์ชันที่คุณพูดถึง) จะเป็นหนึ่งในขั้นตอนสุดท้าย (หรือคุณสามารถใช้ส่วนต่อประสาน REST ใน Express)