REST API สำหรับเว็บไซต์ที่ใช้ Facebook ในการตรวจสอบสิทธิ์


86

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

ตอนนี้เราต้องการสร้างแอปพลิเคชัน iPhone สำหรับไซต์ของเราและยังมี API สาธารณะสำหรับให้ผู้อื่นใช้บริการของเรา

คำถามนี้เกี่ยวกับวิธีการตรวจสอบสิทธิ์กับเว็บไซต์ของเราจากแอป / API และแบ่งออกเป็น 2 ส่วน:

  1. อะไรคือวิธีที่ถูกต้องในการจัดการการตรวจสอบ REST จาก API ไปยังเว็บไซต์ที่ใช้ Facebook OAuth เป็นวิธีการตรวจสอบสิทธิ์เท่านั้น

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

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

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

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

ฉันรู้สึกว่าขาดอะไรบางอย่างที่ชัดเจนมากหรือไม่เข้าใจว่า REST API สาธารณะควรทำงานอย่างไรดังนั้นคำแนะนำและความช่วยเหลือใด ๆ จะได้รับการชื่นชมอย่างมาก


ฉันมีคำถามคล้าย ๆ กันที่stackoverflow.com/questions/30230482/…ซึ่งพูดถึงสิ่งเหล่านี้
JVK

คำตอบ:


99

UPDATE: ดูด้านล่าง

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

เกี่ยวกับลูกค้า:

  1. ใช้ Facebook API เพื่อเข้าสู่ระบบและรับรหัส OAUTH2
  2. แลกเปลี่ยนรหัสนี้เป็นโทเค็นการเข้าถึง
  3. ในการเรียกใช้ API ที่กำหนดเองทุกครั้งฉันจะรวม ID ผู้ใช้ Facebook และโทเค็นการเข้าถึง

บน API (สำหรับทุกวิธีที่ต้องการการตรวจสอบผู้ใช้):

  1. ขอกราฟ / me Facebook โดยใช้โทเค็นการเข้าถึงจากด้านบน
  2. ตรวจสอบว่ารหัสผู้ใช้ Facebook ที่ส่งคืนตรงกับรหัสผู้ใช้ที่ส่งไปยัง API ของฉันจากด้านบน
  3. หากโทเค็นการเข้าถึงหมดอายุจำเป็นต้องมีการสื่อสารเพิ่มเติม

ฉันยังไม่ได้ทดสอบสิ่งนี้ มันฟังดูยังไง?

--- Update: 27 กรกฎาคม 2014 ตอบคำถาม ---

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

เกี่ยวกับลูกค้า:

  1. ใช้ Facebook API เพื่อเข้าสู่ระบบและรับรหัส OAUTH2
  2. แลกเปลี่ยนรหัสนี้เป็นโทเค็นการเข้าถึง
  3. ขอโทเค็นการเข้าถึงจากAPI ของฉันรวมถึงโทเค็น Facebook เป็นพารามิเตอร์

บน API

  1. รับคำขอโทเค็นการเข้าถึง
  2. ขอกราฟ / me Facebook โดยใช้โทเค็นการเข้าถึง facebook
  3. ตรวจสอบว่ามีผู้ใช้ Facebook และตรงกับผู้ใช้ในฐานข้อมูลของฉัน
  4. สร้างโทเค็นการเข้าถึงของฉันเองบันทึกและส่งคืนให้กับไคลเอนต์เพื่อใช้จากจุดนี้ไปข้างหน้า

เฮ้นั่นเป็นการตอบกลับช้า แต่ดูเหมือนว่าวิธีแก้ปัญหาของคุณจะแก้ไขปัญหาที่ฉันพบในคำตอบแรกของฉัน แน่นอนว่าคุณต้องใช้ HTTPS เพื่อไม่ให้ส่งคู่ (id, token) บนสายในข้อความที่ชัดเจน แต่ดูเหมือนว่ามันจะใช้ได้!
Olivier Lance

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

ฉันพบว่าการเก็บความลับ FB ในแอปมือถือเป็นการปฏิบัติที่ไม่ดี คำแนะนำของ Facebook เพื่อจัดเก็บไว้บนเซิร์ฟเวอร์ของคุณเท่านั้น Developers.facebook.com/docs/opengraph/using-actions/…
Der_Meister

หากเราส่ง user_id และ access_token ไปยังเซิร์ฟเวอร์ API ทุกครั้ง (เป็นโพสต์ / รับพารามิเตอร์) มันจะสร้างช่องโหว่ด้านความปลอดภัยหรือไม่หากมีบางคนสามารถสกัดกั้นการเชื่อมต่อได้
Nathan Do

@NathanDo ใช้ HTTPS ระหว่างไคลเอนต์และเซิร์ฟเวอร์ API และไม่ควรเป็นปัญหาหากมีคนขัดขวางการเชื่อมต่อ (ช่องโหว่ประเภท Heartbleed กัน)
dcr

15

นี่คือการใช้งานของฉันโดยใช้ JWTs (JSON Web Tokens) โดยทั่วไปคล้ายกับคำตอบที่อัปเดตของ Chris ฉันใช้ Facebook JS SDK และ JWT

นี่คือการนำไปใช้ของฉัน

  1. ไคลเอนต์:ใช้ Facebook JS SDK เพื่อเข้าสู่ระบบและรับโทเค็นการเข้าถึง

  2. ไคลเอนต์:ขอ JWT จาก API ของฉันโดยเรียก/verify-access-tokenจุดสิ้นสุด

  3. MyAPI:รับโทเค็นการเข้าถึงตรวจสอบโดยเรียก/meจุดสิ้นสุดของ Facebook API

  4. MyAPI:หากโทเค็นการเข้าถึงถูกต้องค้นหาผู้ใช้จากฐานข้อมูลบันทึกผู้ใช้หากมีอยู่ สร้าง JWT โดยมีฟิลด์ที่จำเป็นเป็น payload กำหนดวันหมดอายุลงชื่อด้วยคีย์ลับและส่งกลับไปยังไคลเอนต์

  5. ลูกค้า:จัดเก็บ JWT ในที่จัดเก็บในตัวเครื่อง

  6. ไคลเอนต์:ส่งโทเค็น (JWT จากขั้นตอนที่ 5) พร้อมกับคำขอสำหรับการเรียก API ครั้งถัดไป

  7. MyAPI:ตรวจสอบโทเค็นด้วยรหัสลับหากโทเค็นถูกต้องให้แลกเปลี่ยนโทเค็นเป็นโทเค็นใหม่ส่งกลับไปยังไคลเอ็นต์พร้อมกับการตอบกลับ API (ไม่มีการเรียก API ภายนอกสำหรับการตรวจสอบโทเค็นที่นี่) [หากโทเค็นไม่ถูกต้อง / ไคลเอนต์คำขอหมดอายุให้ตรวจสอบสิทธิ์อีกครั้งและทำซ้ำจาก 1]

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

ทุกโทเค็นใช้ครั้งเดียว

อ่านคำตอบเพิ่มเติมเกี่ยวกับความปลอดภัยและ JWT

JWT. ปลอดภัยแค่ไหน

ถ้าคุณสามารถถอดรหัส JWT ได้จะปลอดภัยแค่ไหน?

JSON Web Tokens (JWT) เป็นโทเค็นการระบุผู้ใช้และการพิสูจน์ตัวตน


3
ฉันเดาว่า # 3 ควรเป็น/debug_tokenดังนั้นคุณสามารถตรวจสอบได้ว่าโทเค็นมีไว้สำหรับแอปพลิเคชันของคุณจริงๆ
Peppe LG

2
อย่าร้องขอaccess_tokenในไคลเอนต์ ใช้ "โค้ดเวิร์กโฟลว์" ผ่านcodeการ MyAPI และทำให้การเดินทางอีกรอบใน Facebook เพื่อแลกเปลี่ยนกับcode access_tokenมีคำอธิบายเพิ่มเติมอย่างละเอียดที่นี่: developers.facebook.com/docs/facebook-login/security
omikron

5

ฉันกำลังพยายามตอบคำถามเดียวกันนี้และเพิ่งผ่านการอ่านมามากมายเมื่อเร็ว ๆ นี้ ...

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

ด้วยเหตุนี้และในแง่ของการพัฒนาสิ่งต่าง ๆ ตั้งแต่เขียนบทความแรกนี่คือสิ่งที่ฉันคิดว่าจะทำ:

  • HTTPS ทุกที่ - สิ่งนี้ช่วยให้คุณลืม HMAC, การลงนาม, nonce, ...

  • ใช้ OAuth2:

    • เมื่อคำขอรับรองความถูกต้องมาจากแอป / เว็บไซต์ของฉันเองให้ใช้ 'เคล็ดลับ' (หรือรูปแบบอื่น) ที่อธิบายไว้ในการตอบกลับบทความที่กล่าวถึงก่อนหน้านี้

    • ในกรณีของฉันฉันมีผู้ใช้สองประเภท: ผู้ที่มีข้อมูลรับรองการเข้าสู่ระบบ / รหัสผ่านแบบคลาสสิกและผู้ที่ลงทะเบียนกับ Facebook Connect
      ดังนั้นฉันจะให้แบบฟอร์มการเข้าสู่ระบบปกติโดยใช้ปุ่ม "เข้าสู่ระบบด้วย Facebook" หากผู้ใช้เข้าสู่ระบบด้วยข้อมูลรับรอง "คลาสสิก" ฉันเพียงแค่ส่งข้อมูลเหล่านี้ไปยังจุดสิ้นสุด OAuth2 ของฉันด้วยไฟล์grant_type=password.
      ถ้าเขาเลือกที่จะเข้าสู่ระบบผ่าน Facebook ฉันคิดว่านั่นจะเป็นกระบวนการสองขั้นตอน:

      • ก่อนอื่นให้ใช้ Facebook iOS SDK เพื่อเปิด FBSession
      • เมื่อเสร็จแล้วและแอปจะได้รับการควบคุมย้อนกลับควรมีวิธีรับ ID Facebook สำหรับผู้ใช้นั้น ฉันจะส่ง ID นี้เพียงอย่างเดียวไปยังปลายทาง OAuth2 ของฉันพร้อมกับสิทธิ์ส่วนขยายที่เซิร์ฟเวอร์ของฉันเข้าใจว่า "ใช้ ID ผู้ใช้ FB"

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

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

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

สิ่งที่ทำเช่นนี้:

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

ดูดีขึ้น?


1
ขอบคุณสำหรับการตอบกลับของคุณ! ฉันเคยคิดเกี่ยวกับสิ่งที่คุณพูดส่วนใหญ่ แต่ข้อกังวลหลักที่ฉันมีกับการใช้ FB iOS SDK จากนั้นการส่ง ID ผู้ใช้ Facebook คือการส่ง ID ใด ๆ ที่คุณต้องการไปยังจุดสิ้นสุด API ของคุณไม่ใช่เรื่องง่ายและอ้างว่าเป็น ผู้ใช้รายอื่น? นี่คือที่ที่ฉันมักจะจมปลัก ..
อดัม

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

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