Tôi đang cố gắng thiết kế các API REST để hỗ trợ các ứng dụng di động khác nhau (các ứng dụng iOS và Android). Các ứng dụng này sẽ cho phép người dùng đăng nhập bằng cách sử dụng đăng nhập facebook cùng với xác thực email của chính chúng tôi. Bạn có thể tham khảo sơ đồ dưới đây để hiểu thiết kế của tôiThiết kế Kiến trúc - REST API để hỗ trợ Đăng nhập Facebook được thực hiện bởi Ứng dụng di động
Có hai cấp độ của nơi cấp phép mất:
Đầu tiên là "Khách hàng (hoặc App) Authorization" có sử dụng OAuth2. Vì vậy, khi người dùng cài đặt ứng dụng của chúng tôi trên thiết bị di động và bắt đầu ứng dụng, thì điều đầu tiên, ứng dụng tạo "Ủy quyền ứng dụng (Client)" như được hiển thị trong sơ đồ trên (hình ảnh thứ nhất). Và máy chủ gửi lại một thời gian dài access_token
cho khách hàng để sử dụng cho tất cả các cuộc gọi tiếp theo. Đây là câu hỏi của tôi là:
Q1) Bạn có thể thấy khách hàng đang gửi client_key
và client_secret
và tôi lưu trữ chúng trong bảng client_info
. Bí mật này có nên ở dạng văn bản thuần túy hay phải ở định dạng có thể giải mã được không? Nếu tôi mã hóa nó, tôi vẫn cần giữ mã khóa ở đâu đó trong hệ thống của mình. Vậy làm thế nào nó sẽ làm cho nó an toàn? Cũng trong mọi cuộc gọi, giải mã sẽ là một chi phí.
Q2) Có được lưu vào bộ nhớ cache access_token
cho ứng dụng khách ở định dạng văn bản thuần túy khi sử dụng lại và sử dụng bộ nhớ cache đó trước không?
Q3) Để an toàn hơn, tôi yêu cầu khách hàng gửi appsecret_proof
để đảm bảo access_token, họ đang gửi chỉ thuộc về khách hàng này. Nó sử dụng cùng một khái niệm như Facebook https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof. Và nó là hash_hmac('sha256', access_token, client_secret)
Q4) Chúng tôi sẽ chỉ có 2 ứng dụng dành cho thiết bị di động (mỗi cho iOS và Android) và không cung cấp cho bên thứ ba sử dụng API của chúng tôi để phát triển các ứng dụng khác. Điều đó có nghĩa, bảng client_info
của chúng tôi sẽ chỉ có hai hàng một cho mỗi loại ứng dụng. Vì vậy, có ổn không, trong mã ứng dụng, chúng tôi giữ mã số client_key
và client_secret
được mã hóa cứng? Nếu có, thì trong tương lai khi chúng ta phải làm mất hiệu lực và sử dụng bí mật mới thì làm thế nào chúng ta sẽ đạt được thay thế những thông tin đó?
Q5) Vì đây là ứng dụng của riêng chúng tôi trong vài năm nên sẽ có nhiều access_token sẽ được tạo trên cùng một số client_key
và client_secret
. Để lưu tất cả chúng, bạn nên lưu client_key
làm khóa và array of all access_tokens
làm giá trị trong redis. Trong tương lai, khi chúng tôi sẽ mở API của chúng tôi cho bên thứ ba, thì thiết kế lưu trữ redis này vẫn có thể mở rộng?
=================
Sau đó, người dùng quyết định thực hiện một số thao tác trên ứng dụng của tôi, cho rằng chúng ta cần phải sử dụng để đăng nhập vào tài khoản của mình. Đối với người dùng đó, hãy nhấp vào "đăng nhập facebook". Ứng dụng của tôi nhận được facebook access_token
và id người dùng fb từ facebook và chuyển các thông tin đó tới máy chủ API (như được hiển thị trong biểu đồ thứ 2). Máy chủ API nhận mã thông báo đó và gọi API facebook để xác thực access_token
của nó. Khi mã thông báo được xác thực, máy chủ sử dụng một số siêu dữ liệu có liên quan đến người dùng đó cùng với mã thông báo truy cập FB để tạo user_access_token
của riêng chúng tôi, cho phép nói utoken
. Và vượt qua điều đó utoken
quay lại khách hàng để trả lại trong mọi cuộc gọi API cụ thể của người dùng tiếp theo. Dưới đây là câu hỏi của tôi là:
Q1) Có ok để lưu rằng utoken
trong cơ sở dữ liệu, user_token
bảng. Nên utoken
này ở dạng văn bản thuần túy hay phải ở định dạng có thể giải mã được? Nếu tôi mã hóa nó, tôi vẫn cần giữ mã khóa ở đâu đó trong hệ thống của mình. Vậy làm thế nào nó sẽ làm cho nó an toàn? Cũng trong mọi cuộc gọi, giải mã sẽ là một chi phí.
Q2) Trong mọi cuộc gọi API cụ thể của người dùng, tôi có nên gọi cho facebook mỗi lần kiểm tra facebook access_token
vẫn hợp lệ không? Tôi tin rằng tôi không nên, vì điều đó sẽ không nhận được bất cứ điều gì với tôi. Xin lưu ý, Facebook CHỈ được sử dụng cho "đăng nhập facebook".
Q3) Thông tin tôi cần mã hóa để tạo ra utoken
là gì? Tôi đang suy nghĩ để có một mảng băm hoặc liên kết của người dùng email
, user id
, role
và facebook token
và sau đó tuần tự hóa cấu trúc dữ liệu đó và cuối cùng mã hóa cấu trúc đó. Bạn có nghĩ rằng đó là đủ tốt. Tôi hiểu nó theo yêu cầu của tôi, nhưng như là một ứng dụng tiêu chuẩn hoặc phổ biến, họ có đủ tốt không? Hoặc là có bất kỳ thực hành tốt nhất?
Q4) Khách hàng có nên lưu trữ utoken
trong cookie/bộ nhớ cache của mình không? Điều đó không đáng sợ sao?
Q5) Xin lưu ý rằng người dùng có thể có nhiều thiết bị, đăng nhập bằng thông tin xác thực người dùng tương tự. Điều đó có nghĩa, trong bảng user_token, chúng tôi sẽ phải lưu trữ nhiều utokens
cho những phiên đăng nhập đó, trong khi tất cả chúng sẽ thuộc về cùng một người dùng. Điều đó có đúng không?
Đề xuất thiết kế hơi quen thuộc với tôi REST API for website which uses Facebook for authentication