2008-10-29 26 views
65

Tôi đang bắt đầu xây dựng một API REST cho một dự án mà tôi đang thực hiện, và điều đó đã khiến tôi thực hiện một nghiên cứu nhỏ là cách tốt nhất để xây dựng một API bằng cách sử dụng RoR. Tôi tìm ra khá nhanh chóng theo mặc định, các mô hình được mở cho thế giới và có thể được gọi qua URL bằng cách đặt một ".xml" ở cuối URL và chuyển các tham số thích hợp.Tìm kiếm các đề xuất để xây dựng một API REST an toàn trong Ruby on Rails

Vì vậy, câu hỏi tiếp theo đến. Làm cách nào để bảo vệ ứng dụng của tôi ngăn chặn các thay đổi trái phép? Trong một số nghiên cứu, tôi đã tìm thấy một số bài viết nói về attr_accessibleattr_protected và cách chúng có thể được sử dụng. URL cụ thể mà tôi đã tìm thấy nói về những điều này đã được đăng trở lại vào tháng Năm '07 (here).

Như với tất cả mọi thứ của ruby, tôi chắc chắn rằng mọi thứ đã phát triển kể từ đó. Vì vậy, câu hỏi của tôi là, đây vẫn là cách tốt nhất để bảo đảm một API REST trong RoR?

Nếu bạn không đề xuất điều gì trong dự án "dự án mới" hoặc kịch bản "dự án hiện tại"?

+0

Nếu khách hàng biết cách thao tác các URI của bạn (bằng cách thêm .xml hoặc cách khác) thì API của bạn không phải là REST. – aehlke

+0

đây là thư viện Oauth 2.0 Server tốt cho ruby ​​https://github.com/Lelylan/rest-oauth2-server – sparkle

Trả lời

100

Có một số lược đồ để xác thực yêu cầu API và chúng khác với xác thực thông thường được cung cấp bởi plugin như restful_authentication hoặc actions_as_authenticated. Quan trọng nhất, khách hàng sẽ không duy trì phiên, vì vậy không có khái niệm về đăng nhập.

HTTP Authentication

Bạn có thể sử dụng xác thực HTTP cơ bản. Đối với điều này, khách hàng của API sẽ sử dụng một tên người dùng và mật khẩu thường xuyên và chỉ cần đặt nó trong URL như vậy:

http://myusername:[email protected]/ 

Tôi tin restful_authentication hỗ trợ này ra khỏi hộp, vì vậy bạn có thể bỏ qua hay không một người nào đó đang sử dụng ứng dụng của bạn thông qua API hoặc qua trình duyệt.

Một nhược điểm ở đây là bạn đang yêu cầu người dùng đặt tên người dùng và mật khẩu của họ rõ ràng trong mọi yêu cầu. Bằng cách thực hiện nó qua SSL, bạn có thể thực hiện điều này an toàn.

Tôi không nghĩ mình đã từng thấy một API sử dụng điều này. Nó có vẻ như là một ý tưởng rất tốt đối với tôi, đặc biệt là vì nó được hỗ trợ bởi các chương trình xác thực hiện tại, nên tôi không biết vấn đề là gì.

API chính

Một cách dễ dàng để cho phép xác thực API là sử dụng phím API. Về cơ bản nó là tên người dùng cho một dịch vụ từ xa. Khi ai đó đăng ký sử dụng API của bạn, bạn cung cấp cho họ khóa API. Điều này cần phải được thông qua với mỗi yêu cầu.

Một nhược điểm ở đây là nếu ai đó nhận khóa API của người khác, họ có thể đưa ra yêu cầu với tư cách người dùng đó. Tôi nghĩ rằng bằng cách làm cho tất cả các yêu cầu API của bạn sử dụng HTTPS (SSL), bạn có thể bù đắp rủi ro này một chút.

Một nhược điểm khác là người dùng sử dụng thông tin đăng nhập xác thực giống nhau (khóa API) ở mọi nơi họ đến. Nếu họ muốn thu hồi quyền truy cập vào ứng dụng API, tùy chọn duy nhất của họ là thay đổi khóa API, điều này sẽ vô hiệu hóa tất cả các ứng dụng khách khác. Điều này có thể được giảm nhẹ bằng cách cho phép người dùng tạo nhiều khóa API.

API Key + ký chính Secret

Deprecated (loại) - xem OAuth dưới đây

đáng kể phức tạp được ký kết theo yêu cầu với một chìa khóa bí mật. Đây là những gì Amazon Web Services (S3, EC2, và như vậy). Về cơ bản, bạn cung cấp cho người dùng 2 khóa: khóa API của họ (ví dụ: tên người dùng) và khóa bí mật của họ (ví dụ: mật khẩu). Khóa API được truyền đi với mỗi yêu cầu, nhưng khóa bí mật thì không. Thay vào đó, nó được sử dụng để ký mỗi yêu cầu, thường bằng cách thêm một tham số khác.

IIRC, Amazon hoàn thành điều này bằng cách lấy tất cả tham số cho yêu cầu và sắp xếp chúng theo tên thông số. Sau đó, chuỗi này được băm, sử dụng khóa bí mật của người dùng làm khóa băm. Giá trị mới này được nối thêm dưới dạng tham số mới cho yêu cầu trước khi được gửi. Về phía Amazon, họ cũng làm như vậy. Họ lấy tất cả các tham số (ngoại trừ chữ ký), sắp xếp chúng và băm bằng khóa bí mật. Nếu điều này khớp với chữ ký, họ biết yêu cầu là hợp pháp.

Nhược điểm ở đây là sự phức tạp. Bắt chương trình này hoạt động chính xác là một nỗi đau, cả cho nhà phát triển API và khách hàng. Mong đợi rất nhiều cuộc gọi hỗ trợ và email tức giận từ các nhà phát triển ứng dụng khách, những người không thể làm mọi thứ.

OAuth

Để chống lại một số vấn đề phức tạp với phím + ký bí mật, một tiêu chuẩn đã nổi lên gọi OAuth. Tại OAuth cốt lõi là một hương vị của ký + khóa bí mật, nhưng phần lớn nó được tiêu chuẩn hóa và được đưa vào libraries for many languages.

Nói chung, dễ dàng hơn nhiều đối với cả nhà sản xuất API và người tiêu dùng để sử dụng OAuth thay vì tạo hệ thống khóa/chữ ký của riêng bạn.

OAuth cũng vốn phân đoạn quyền truy cập, cung cấp thông tin đăng nhập truy cập khác nhau cho từng người tiêu dùng API. Điều này cho phép người dùng thu hồi có chọn lọc truy cập mà không ảnh hưởng đến các ứng dụng tiêu thụ khác của họ.

Đặc biệt đối với Ruby, có OAuth gem cung cấp hỗ trợ ngoài hộp cho cả nhà sản xuất và người tiêu dùng của OAuth. Tôi đã sử dụng đá quý này để xây dựng một API và cũng để tiêu thụ các API OAuth và rất ấn tượng. Nếu bạn nghĩ rằng ứng dụng của bạn cần OAuth (trái với lược đồ khóa API đơn giản hơn), thì tôi có thể dễ dàng khuyên bạn sử dụng đá quý OAuth.

+0

nhiều người đang đi xuống khóa API + đường dẫn ký, bất kỳ ai biết nếu có 'cách tốt hơn'? ! – MatthewFord

+0

Câu trả lời hay - điều này cuối cùng đã xóa nó cho tôi với các cấp độ khác nhau. Cảm ơn! –

+2

Có hai vấn đề lớn với HTTP "Ủy quyền:". Đầu tiên là máy chủ quyết định trên lược đồ auth, điều đó có nghĩa rằng xác thực Digest không ngăn chặn sự xâm phạm mật khẩu của một MITM (chỉ giả vờ rằng bạn chỉ hỗ trợ Basic). Thứ hai là xác thực cơ bản không giới hạn ở một đường dẫn, vì vậy bất kỳ ai trên máy chủ web chia sẻ đều có thể nhận mật khẩu của người khác (nhiều người chuyển sang miền phụ vì lý do này, cùng với cookie và cấu hình Apache thông thường hơn). –

3

Tôi đang đối mặt với các câu hỏi tương tự như bạn hiện tại vì tôi cũng đang xây dựng một API REST cho ứng dụng đường ray.

Tôi khuyên bạn nên đảm bảo rằng chỉ các thuộc tính có thể được người dùng chỉnh sửa mới được đánh dấu bằng attr_accessible. Điều này sẽ thiết lập một danh sách trắng các thuộc tính có thể được gán bằng cách sử dụng update_attributes.

Những gì tôi làm là một cái gì đó như thế này:

class Model < ActiveRecord::Base 
     attr_accessible nil 
    end 

Tất cả các mô hình của tôi kế thừa từ đó, vì vậy mà họ buộc phải xác định attr_accessible cho bất kỳ lĩnh vực mà họ muốn thực hiện khối lượng chuyển nhượng. Cá nhân, tôi muốn có một cách để kích hoạt hành vi này theo mặc định (có thể có, và tôi không biết về nó).

Chỉ cần bạn biết ai đó có thể giao hàng loạt tài sản không chỉ bằng cách sử dụng REST api mà còn sử dụng bài đăng biểu mẫu thông thường.

7

Làm cách nào để đảm bảo ứng dụng của tôi ngăn chặn thay đổi trái phép?

attr_accessibleattr_protected đều hữu ích để kiểm soát khả năng thực hiện chuyển nhượng hàng loạt trên mô hình ActiveRecord. Bạn chắc chắn muốn sử dụng attr_protected để ngăn chặn các cuộc tấn công dạng tiêm; xem Use attr_protected or we will hack you.

Ngoài ra, để ngăn mọi người truy cập bộ điều khiển trong ứng dụng Rails, bạn gần như chắc chắn sẽ cần một số loại hệ thống xác thực người dùng và đặt before_filter trong bộ điều khiển của mình để đảm bảo rằng bạn có người dùng được ủy quyền thực hiện yêu cầu trước khi bạn cho phép hành động của trình điều khiển được yêu cầu thực hiện.

Xem Ruby on Rails Security Guide (một phần của Dự án tài liệu đường ray) để có được nhiều thông tin hữu ích hơn.

0

Một cách tiếp cận khác giúp bạn tự mình xây dựng nhiều thứ là sử dụng một cái gì đó như http://www.3scale.net/ xử lý các khóa, mã thông báo, hạn ngạch, vv cho các nhà phát triển cá nhân. Nó cũng phân tích và tạo cổng thông tin dành cho nhà phát triển.

Có plugin ruby ​​/ rails ruby API plugin sẽ áp dụng cho các chính sách lưu lượng truy cập khi đến - bạn có thể sử dụng nó cùng với oAuth gem. Bạn cũng có thể sử dụng nó bằng cách giảm véc ni ở phía trước ứng dụng và sử dụng mod ma thuật varnish: Varnish API Module.

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