Thiết kế để xác thực Facebook trong một ứng dụng iOS cũng truy cập dịch vụ web được bảo mật


402

Mục tiêu: Cho phép người dùng xác thực với Facebook vào ứng dụng iOS yêu cầu quyền truy cập vào dịch vụ web được bảo vệ mà tôi đang chạy.

Giả định: Có một hệ thống xác thực (và đăng ký) gốc dành cho những người dùng chọn không sử dụng Facebook để đăng nhập.

Chi tiết:

  • Giả sử chúng tôi muốn cung cấp tùy chọn cho người dùng đăng nhập bằng Facebook mà không cần tạo tài khoản / thông tin đăng nhập riêng cho hệ thống của chúng tôi.
  • Vì chúng tôi hỗ trợ cơ chế xác thực riêng của chúng tôi (tên người dùng và mật khẩu), chúng tôi có ID người dùng của riêng mình và cấp mã thông báo xác thực được sử dụng cho các tương tác tiếp theo sau khi xác thực thông tin ban đầu.

Tôi ngạc nhiên rằng Facebook không có các thực tiễn tốt nhất cho điều này trong tài liệu dành cho nhà phát triển của họ. Tất cả các tài liệu hiện có đều giả sử bạn đang xây dựng FB auth vào một trang web hoặc một ứng dụng di động độc lập không có dịch vụ yêu cầu xác thực.

Đây là những suy nghĩ ban đầu của tôi về cách nó sẽ được thiết kế nhưng muốn xác nhận xem nó có đúng không.

  1. Khách hàng bật đăng nhập Facebook iOS
  2. UI Người dùng đăng nhập bằng thông tin đăng nhập Facebook và nhận mã thông báo truy cập
  3. Ứng dụng iOS chuyển mã thông báo truy cập đến máy chủ của chúng tôi
  4. Máy chủ của chúng tôi nói chuyện với API đồ thị FB bằng cách sử dụng mã thông báo truy cập để (a) xác thực mã thông báo và (b) lấy ID người dùng FB cho mã thông báo truy cập đó.

    ví dụ: máy chủ của chúng tôi sẽ gọi https://graph.facebook.com/me/?access_token=XYZ sẽ trả về thông tin hồ sơ trong một đối tượng JSON

  5. Giả sử nó hợp lệ, máy chủ của chúng tôi trích xuất ID người dùng từ đối tượng JSON và kiểm tra xem người dùng đã có tài khoản chưa. Nếu vậy, chúng tôi phát hành vé xác thực của riêng mình cho khách hàng để sử dụng cho phiên đó. Nếu người dùng không có tài khoản, chúng tôi sẽ tạo một tài khoản mới với ID người dùng Facebook, gán UserID duy nhất của riêng chúng tôi và cấp vé xác thực của chúng tôi.

  6. Sau đó, khách hàng sẽ trả lại vé xác thực cho các tương tác tiếp theo cần xác thực.

Đây có vẻ là cách tiếp cận đúng với tôi nhưng không chắc chắn liệu tôi có đang thiếu thứ gì đó cực kỳ cơ bản và đi sai đường (phức tạp) không.


1
Làm thế nào điều này đã được giải quyết? Tôi cũng đang xem xét việc chuyển mã thông báo truy cập và quay vòng người dùng trên máy chủ. Có vẻ hàn lâm, nhưng đang hỏi.
Chris Van Buskirk

Đây là triển khai của tôi bằng cách sử dụng đường ray và phát minh: stackoverflow.com/questions/7232490/ triệt
Matt

Tại sao không vượt qua toàn bộ auth_hash thay vì phải thực hiện hai cuộc gọi đến API FB (một từ thiết bị iOS và một lần từ máy chủ)?
bsiddiqui

1
Điều gì xảy ra nếu bạn muốn đăng nhập từ một thiết bị khác (có nghĩa là bạn không có vé xác thực)? Và nếu bạn vừa nhận được một vé xác thực mới, điều gì ngăn ai đó chiếm quyền điều khiển id / mã thông báo facebook trên đường và sử dụng nó trên thiết bị của chính anh ta?
Amitloaf

Vì tò mò, ở bước 5, tại sao lại phát hành vé auth của riêng bạn? Bạn có thể không sử dụng mã thông báo truy cập Facebook cho mỗi cuộc gọi máy chủ tiếp theo không? Tôi nhận ra rằng nó sẽ yêu cầu một cuộc gọi từ máy chủ đến API Facebook cho mọi ứng dụng -> cuộc gọi máy chủ thay vì chỉ cuộc gọi đầu tiên.
Anders

Câu trả lời:


80

Tôi chỉ tự mình giải quyết vấn đề này và đây là phần khiến tôi bực mình:

Ở bước 5 của bạn ... Người dùng có thể đăng ký tài khoản với bạn hoàn toàn tách biệt với ID Facebook của họ, phải không? Sau đó, một thời gian khác họ đăng nhập bằng Facebook .... Và bạn vừa tạo cho họ một tài khoản thứ hai và mất tài khoản đầu tiên.

Cần phải có một cách để đăng nhập vào dịch vụ web của bạn, sau đó đăng nhập vào facebook và nắm bắt sự liên kết giữa ID facebook và tài khoản cục bộ.

Ngoài ra, kế hoạch của bạn có vẻ vững chắc.

Cập nhật : Facebook đã thêm một tài liệu phác thảo một kịch bản như vậy TẠI ĐÂY


7
Đúng, tôi đã xem xét điều đó và bạn phát hiện ra. Chúng tôi dự định hợp nhất các tài khoản nếu đó là cùng một địa chỉ email và nếu không, chúng tôi sẽ tạo một cách khác để hợp nhất chúng.
TMC

Thư viện máy chủ nào bạn đang sử dụng ở phía Máy chủ để thực hiện yêu cầu?
TimLeung

7
@TimLeung - Hiểu biết của tôi là mã thông báo truy cập nhúng ID ứng dụng và bạn không thể có mã thông báo truy cập mà KHÔNG CÓ ID ứng dụng được nướng trong đó.
Dan Ray

1
@TimLeunge: Chúng tôi đang sử dụng API đồ thị cho các yêu cầu có mã thông báo truy cập của người dùng.
TMC

29

Sử dụng https để truyền mã thông báo xác thực đến máy chủ của bạn, như đã nêu của Facebook

Chia sẻ mã thông báo truy cập

Chính sách dữ liệu của chúng tôi nghiêm cấm mọi chia sẻ Mã thông báo truy cập cho ứng dụng của bạn với bất kỳ ứng dụng nào khác. Tuy nhiên, chúng tôi cho phép các nhà phát triển chia sẻ Mã thông báo giữa triển khai gốc và triển khai máy chủ của cùng một Ứng dụng (nghĩa là sử dụng cùng một ID ứng dụng) miễn là việc chuyển tiền diễn ra bằng HTTPS.


16

Một vấn đề tôi có thể thấy với chiến lược này, đó là ai đó có thể cung cấp cho bạn mã thông báo truy cập thu được cho một ứng dụng facebook khác. Theo tôi biết, không có cách nào để xác minh rằng mã thông báo truy cập là dành cho ứng dụng của bạn, vì vậy bạn sẽ tiếp tục và sử dụng nó.

Nó không có vẻ rất có hại, mặc dù. Nói chung, mọi người / ứng dụng cố gắng bảo vệ mã thông báo truy cập, thay vì chia sẻ chúng.

Một khả năng khai thác này có thể là, cho ai đó tạo trang web hoặc ứng dụng di động của riêng họ, lấy mã thông báo truy cập cho người dùng của họ và cố gắng xác thực chúng bằng API của bạn. Nếu điều này thành công (người dùng có tài khoản facebook trong trang web của bạn), trang web độc hại sẽ có thể sử dụng API của bạn mạo danh người dùng.

Đó là một chút của một cú sút xa, nhưng tôi nghĩ rằng nó có thể làm việc.

Chỉnh sửa: Dường như có một cách để xác thực mã thông báo truy cập sau khi tất cả. Xem câu trả lời của @Daaniel về câu hỏi Nhận id ứng dụng từ mã thông báo truy cập của người dùng (hoặc xác minh ứng dụng nguồn cho mã thông báo) .


Gửi appsecret_proofsẽ ngăn chặn điều này (xem tại đây )
Tony

@Tony bạn có thể giải thích làm thế nào để appsecret_proofgiúp đỡ ở đây? Theo tôi hiểu, nó phục vụ để chứng minh với Facebook rằng máy chủ biết khóa bí mật. Tuy nhiên, ivant đã đề cập đến một ứng dụng độc hại lấy mã thông báo và sau đó gửi chúng đến API của bạn. Máy chủ có thể xác minh ID ứng dụng, nhưng ID ứng dụng có thể dễ dàng bị giả mạo bởi một ứng dụng độc hại. Vậy ... làm thế nào để giảm thiểu điều này?
YSK

3
Bạn có thể xác minh rằng mã thông báo đã được tạo cho ứng dụng của bạn thông qua https://graph.facebook.com/app/?access_token=[user_access_token]đó trả về id ứng dụng và sau đó so sánh các id ứng dụng
Nader Alexan

4

giải pháp của bạn hoàn toàn hiệu quả.

Có thể là một giải pháp thay thế: tại sao không nhận email từ khách hàng từ yêu cầu dịch vụ xã hội ban đầu và gửi đến dịch vụ web của bạn? Dịch vụ web chỉ có thể lưu trữ email và có thể là một Social_provider. Tôi hiểu rằng dịch vụ web của bạn sẽ không thể xác thực email đến từ đâu, nhưng không có mối quan hệ tin cậy cao giữa dịch vụ web của bạn và khách hàng của bạn? Nếu có, có vẻ như bạn có thể phụ thuộc vào email đến từ đúng nơi. Ai đó làm ơn cho tôi biết những gì rõ ràng tôi đang thiếu khiến cách tiếp cận dựa trên email trở nên ngớ ngẩn ...


3
Tôi có thể dễ dàng tìm ra cách khách hàng nói chuyện với máy chủ. Sau đó, tôi chỉ có thể ném email vào nó cho đến khi tôi nhận được một hit. Luôn cần có một số hình thức xác minh
Chris

5
Độ tin cậy và khách hàng cao? Không bao giờ trong cùng một câu, xin vui lòng. Ngoại trừ câu trước tất nhiên.
EralpB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.