2012-12-07 27 views
10

Tôi có một cơ sở dữ liệu đa người thuê nhà với hỗn hợp chínhRest API với cơ sở dữ liệu đa người thuê nhà tách ra bởi khách hàng

clientId - docId 

Định tuyến trông như thế này

/api/controller/clientId/docId 

Đối với chứng thực tôi sử dụng một "toàn cầu "tên người dùng như email + mật khẩu, được gửi trong tiêu đề http của mọi yêu cầu qua https. Tên người dùng ánh xạ một cách rõ ràng cho một khách hàng và có sẵn trên backend.

Cách để làm điều đó đúng cách với phần còn lại và có bảo mật tốt nhất là gì?

  1. Route như trên và chỉ cần xác minh rằng ClientId theo tên người dùng là như nhau so với định tuyến

hoặc

  1. Thay đổi định tuyến như sau và nhận được ClientId từ một cơ sở dữ liệu trước khi lưu một bản ghi?

    /api/controller/docId

Đây có thể là một câu hỏi rõ ràng, nhưng tôi lo lắng về vấn đề an ninh tiềm năng. Hoặc là nó chỉ là không có trí tuệ để đi với định tuyến ngắn hơn?

Cảm ơn!

Trả lời

8

Tôi nghĩ rằng /api/controller/docId có lẽ là ý tưởng hay nhất hoặc sử dụng một khóa đại diện duy nhất để đại diện cho ClientId và docId (sở thích của tôi). Trừ khi bạn cần phải cho phép khách hàng xem tài nguyên khách hàng khác, tôi sẽ ẩn nó khỏi lược đồ URI, lúc tồi tệ nhất nó có thể được coi là rò rỉ thông tin tốt nhất là thừa khi bạn đã xác thực khách hàng và biết họ là ai . Nó cũng là một chi phí, tức là bạn vẫn phải kiểm tra id khách hàng trong url được ánh xạ tới tên người dùng và mật khẩu của yêu cầu, do đó bạn cần truy xuất id ứng dụng trên mỗi yêu cầu.

Nếu bạn xem cách hoạt động của môi trường nhiều người dùng khác, ví dụ: Lực lượng bán hàng của bạn có thể thấy rằng họ phải phỏng đoán khách hàng thông qua cơ chế bảo mật hoặc đủ may mắn để có một id duy nhất cho mọi đối tượng/tài nguyên.

Cách tiếp cận tôi đã thấy là đặt mã nhận diện khách hàng (thường là khóa thay thế của somekind, tránh để lộ các id người dùng khác của db!) Tại gốc của URL, ví dụ:/api/{clientId}/controller/docId. Trong môi trường đa người dùng, mọi tài nguyên có thể là/theo định nghĩa duy nhất cho khách hàng đó.

Một lý do đôi khi đưa ra cho phương pháp này là có một địa chỉ duy nhất mỗi hỗ trợ khách hàng với bộ nhớ đệm .../api/{} ClientId/controller/docid hoặc/api/controller/{ClientId}/docid

Lưu ý ngắn gọn về xác thực cơ bản

Không có gì sai với cách tiếp cận của bạn nhưng hãy xem xét ... bạn có thể truy xuất Id ứng dụng trong khi xác thực mật khẩu và tên người dùng và thêm đó làm xác nhận quyền sở hữu trên IPrinciple. Ít nhất đó là sau đó có sẵn trong mã mà không có bất kỳ thêm db nhìn up để tìm thấy nó (trong vòng đời của yêu cầu đó).

Thực hiện thêm một bước nữa ... xem xét cơ chế xác thực hai bước trong đó mã thông báo được cấp (sau tên người dùng và mật khẩu chính xác) với Id khách hàng thực sự trong mã thông báo là xác nhận quyền sở hữu. Bằng cách này, các yêu cầu tiếp theo với mã thông báo có nghĩa là bạn sẽ không cần gọi lại db cho mọi yêu cầu để xác thực và truy xuất thông tin. Hãy xem mã thông báo người gửi OAuth http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html (hãy chắc chắn ký tên) hoặc một số cách tiếp cận khác ...

5

Phương pháp của Mark hoàn toàn hợp lệ, tuy nhiên, tôi sử dụng /tenant/docid vì mỗi người thuê có cơ sở dữ liệu khác nhau. Nếu bạn không bao gồm người thuê nhà trong URI thì đó sẽ là một nỗi đau thực sự cố gắng quyết định cơ sở dữ liệu nào kết nối và tìm kiếm tài liệu.

+0

Tôi có tình huống tương tự. Bạn đã xem xét để có id người thuê được lưu trữ dưới dạng xác nhận quyền sở hữu của người dùng (hoặc tương tự trên mã thông báo truy cập/thông tin đăng nhập)? Tôi nghĩ rằng có người thuê nhà như một phần của URI là lý tưởng, nhưng nó đòi hỏi nhiều công việc hơn khi áp dụng cho phần mềm hiện có. – bjornhol

+2

@bjornhol Nếu ID người thuê không được bao gồm trong URL thì nó làm cho bộ nhớ đệm cục bộ trở nên khó khăn bởi vì tôi sử dụng số nguyên và không phải là số nhận dạng cho số nhận dạng để có thể có xung đột giữa người thuê. –

Các vấn đề liên quan