2009-05-13 41 views
29

Tôi có một ứng dụng web để lấy dữ liệu từ JSON API mới được tạo của tôi.Làm cách nào để hạn chế quyền truy cập JSON?

Các trang HTML tĩnh của tôi tự động gọi API JSON qua JavaScript từ trang HTML tĩnh.

Làm cách nào để hạn chế quyền truy cập vào JSON API của tôi để chỉ tôi (trang web của tôi) mới có thể gọi từ đó?

Trong trường hợp trợ giúp, API của tôi giống như sau: http://example.com/json/?var1=x&var2=y&var3=z ... tạo JSON thích hợp dựa trên truy vấn.

Tôi đang sử dụng PHP để tạo kết quả JSON ... có thể hạn chế quyền truy cập vào API JSON đơn giản như kiểm tra $_SERVER['HTTP_REFERER'] để đảm bảo API chỉ được gọi từ miền của tôi chứ không phải người dùng từ xa?

+0

Chỉ cần làm rõ, bạn có đang cố gắng làm cho nó chỉ để máy chủ của bạn có thể sử dụng API hay chỉ những người xem trang web từ máy chủ của bạn? –

+1

Api JSON của tôi có tại: http: //example.com/json? ... và tôi chỉ muốn trang web của mình http://example.com có ​​thể truy xuất kết quả từ JSON api của tôi. –

+0

Chỉ vì tò mò, tại sao bạn lại cố gắng làm điều này? Nó sẽ chống lại các hạt của web vì vậy sẽ là tốt để biết lý do đằng sau yêu cầu. – Sam

Trả lời

4

Bất kỳ giải pháp nào ở đây sẽ không hoàn hảo nếu các trang tĩnh sử dụng API của bạn cần phải có trên Internet công cộng. Vì bạn cần có khả năng để trình duyệt của khách hàng gửi yêu cầu và yêu cầu nó được tôn trọng, có thể chỉ là về bất kỳ ai để xem chính xác cách bạn đang tạo URL đó.

Bạn có thể có ứng dụng phía sau API của bạn, kiểm tra liên kết giới thiệu http, nhưng điều đó rất dễ giả nếu ai đó muốn.

Nếu không yêu cầu các trang tĩnh, bạn có thể thử thứ gì đó mà bạn có "khóa" ngắn được tạo bởi API và được bao gồm trong phản hồi HTML của trang đầu tiên được chuyển thành tham số quay lại API. Điều này sẽ thêm phí vào API của bạn mặc dù bạn sẽ phải có máy chủ ở đầu đó duy trì danh sách "khóa" hợp lệ, thời gian hợp lệ cho, v.v.

Vì vậy, bạn có thể thực hiện một số bước mà không tốn nhiều tiền nhưng không khó để có được xung quanh nếu ai đó thực sự muốn, hoặc bạn có thể dành nhiều thời gian hơn để làm cho nó khó hơn một chút, nhưng không có cách nào hoàn hảo để làm điều này nếu API của bạn phải có thể truy cập công khai.

+0

Đây có lẽ là công việc thanh lịch nhất, nhưng tôi đồng ý nó chỉ là một công việc xung quanh và không phải là một giải pháp thực sự (không có). –

+0

Vì vậy, những gì bạn đang nói là ... nếu tôi đã kiểm tra 'HTTP_REFERER' - ít nhất nó cung cấp một số bảo đảm giới hạn *** rằng chỉ có trang web của tôi đang sử dụng JSON api của tôi. Nhưng sau đó một lần nữa, 'HTTP_REFERER' có thể dễ dàng bị giả mạo. –

+0

JamesZ - chính xác. –

4

Câu trả lời ngắn gọn là: bất kỳ ai có thể truy cập vào các trang trên trang web của bạn cũng sẽ có thể truy cập vào API của bạn.

Bạn có thể cố gắng sử dụng API của mình khó khăn hơn bằng cách mã hóa nó theo nhiều cách khác nhau, nhưng vì bạn sẽ phải bao gồm mã JavaScript để giải mã đầu ra của API, bạn sẽ tự thiết lập một cuộc chạy đua vũ trang với bất kỳ ai quyết định họ muốn sử dụng API của bạn thông qua các phương tiện khác. Ngay cả khi bạn sử dụng các khóa ngắn ngủi, một "kẻ tấn công" được xác định có thể luôn luôn chỉ xóa mã HTML của bạn (cùng với khóa hiện tại) ngay trước khi sử dụng API. Nếu tất cả những gì bạn muốn làm là ngăn các trang web khác sử dụng API của bạn trên trang web của họ thì bạn có thể sử dụng tiêu đề Liên kết giới thiệu nhưng lưu ý rằng không phải tất cả trình duyệt đều gửi Liên kết giới thiệu (và một số proxy cũng xóa chúng!). Điều này có nghĩa là bạn muốn cho phép tất cả yêu cầu thiếu liên kết giới thiệu và điều này sẽ chỉ cung cấp cho bạn một phần bảo vệ. Ngoài ra, người giới thiệu có thể dễ dàng giả mạo, vì vậy nếu một số trang web khác thực sự muốn sử dụng API của bạn, họ luôn có thể giả mạo trình duyệt và truy cập API của bạn từ máy chủ của họ.

+1

Tôi không muốn mã hóa nó, tôi chỉ muốn hạn chế "ai" có thể gọi api JSON của tôi. Người duy nhất tôi muốn có thể gọi API là máy chủ web của riêng tôi và không có người dùng từ xa nào. –

+0

Vâng, đó là đoạn cuối của câu trả lời của tôi là gì. Bạn có thể thử sử dụng liên kết giới thiệu nhưng có thể dễ dàng bị giả mạo. –

18

Phương pháp thông thường để hạn chế quyền truy cập vào miền của bạn là thêm vào trước nội dung có thứ gì đó chạy vô hạn.

Ví dụ:

while(1);{"json": "here"} // google uses this method 
for (;;);{"json": "here"} // facebook uses this method 

Vì vậy, khi bạn lấy này qua XMLHttpRequest hoặc bất kỳ phương pháp khác mà bị hạn chế chỉ để tên miền của bạn, bạn biết rằng bạn cần phải phân tích ra các vòng lặp vô hạn. Nhưng nếu nó được tìm nạp thông qua nút tập lệnh:

<script src="http://some.server/secret_api?..."></script> 

Nó sẽ thất bại vì tập lệnh sẽ không bao giờ vượt ra ngoài câu lệnh đầu tiên.

+1

Nói gì? Đề nghị của bạn là tạo ra một vòng lặp vô hạn?Hoặc là tôi hoàn toàn thiếu một cái gì đó ở đây hoặc bạn đang kéo chân của tôi. –

+16

Ngoại trừ bất kỳ ai vẫn có thể gọi nó từ mã phía máy chủ mà không gặp bất kỳ rắc rối nào và chỉ loại bỏ các vòng lặp. –

+4

Có, JameZ, đó là chính xác. Một vòng lặp vô hạn được thêm vào JSON sẽ ngăn không cho JSON của bạn được nạp vào các nút tập lệnh. Có, nó sẽ không ngăn chặn truy cập từ máy chủ đến máy chủ. Đây không phải là giải pháp khắc phục tất cả. Nó chỉ là một lớp bảo mật khác. Nó sẽ ngăn chặn dữ liệu của bạn được tải phía máy khách bằng cách sử dụng nút kịch bản lệnh. – fearphage

17

Tôi nghĩ bạn có thể hiểu sai phần mà yêu cầu JSON được khởi tạo từ trình duyệt của người dùng thay vì từ máy chủ của riêng bạn. Trang HTML tĩnh được gửi đến trình duyệt của người dùng, sau đó nó quay lại và thực thi mã Javascript trên trang. Mã này sẽ mở một kết nối mới trở lại máy chủ của bạn để lấy dữ liệu JSON. Từ quan điểm của tập lệnh PHP của bạn, yêu cầu JSON đến từ đâu đó trong thế giới bên ngoài.

Với cơ chế trên, bạn không thể làm gì để ngăn không cho ai đó gọi API JSON bên ngoài ngữ cảnh của trang HTML của bạn.

+0

Nếu đó là trường hợp, làm thế nào là những người dự đoán của họ "RESTful" api? Hoặc tất cả các API này đều là công khai? –

+1

Nói chung, chúng là các API công khai. Tùy thuộc vào trang web, chúng có thể hoặc có thể không được ghi lại để sử dụng công cộng, nhưng tất cả chúng phải được xây dựng với một mắt hướng tới sự mạnh mẽ khi đối mặt với những người dùng độc hại (hoặc không thể bỏ qua). –

+0

Vì vậy, làm thế nào để mọi người ngăn chặn người dùng gửi một truy vấn REST chỉ đơn giản là đổ tất cả dữ liệu từ cơ sở dữ liệu ứng dụng web. –

5

Theo ý kiến ​​của tôi, bạn không thể hạn chế quyền truy cập, chỉ làm cho khó hơn. Nó giống như hạn chế truy cập bởi sự tối tăm. Các liên kết giới thiệu có thể dễ dàng được giả mạo và thậm chí với khóa ngắn ngủi, một tập lệnh có thể nhận được phản hồi bằng cách liên tục làm mới khóa.

Vì vậy, những gì có thể chúng tôi làm gì?

Xác định sự yếu kém ở đây:

http://www.example.com/json/getUserInfo.php?id=443

Kẻ tấn công bây giờ có thể dễ dàng yêu cầu tất cả các thông tin người dùng từ 1 đến 1.000.000 trong vòng một. Điểm yếu của auto_increment ID là tuyến tính của chúng và chúng dễ đoán.

Giải pháp: sử dụng số nhận dạng duy nhất không phải số cho dữ liệu của bạn.

http://www.example.com/json/getUserInfo.php?userid=XijjP4ow

Bạn không thể lặp qua những. Đúng, bạn vẫn có thể phân tích cú pháp các trang HTML cho các khóa cho tất cả các loại khóa, nhưng kiểu tấn công này khác nhau (và dễ tránh được hơn).

Nhược điểm: tất nhiên bạn không thể sử dụng phương pháp này để hạn chế các truy vấn không phụ thuộc vào khóa, ví dụ: Tìm kiếm.

0

Rất tiếc, có thể tôi đã sai nhưng ... nó có thể được tạo bằng HTTPS không?

Bạn có thể có API của bạn truy cập qua http s (?): //example.com/json/ var1 = x & var2 = y, do đó người tiêu dùng chỉ có thể nhận được chứng thực dữ liệu của bạn ...

+5

SSL không đảm bảo danh tính, nó chỉ ngăn các bên thứ ba thấy dữ liệu của bạn trong khi đang chuyển tiếp giữa trình duyệt và máy chủ. – RQDQ

0

Bạn có, hoặc bạn có thể sử dụng xác thực dựa trên cookie không? Kinh nghiệm của tôi dựa trên việc xác thực các hình thức ASP.NET, nhưng cách tiếp cận tương tự cũng có thể thực hiện được với PHP bằng một mã nhỏ.

Ý tưởng cơ bản là khi người dùng xác thực thông qua ứng dụng web, cookie có giá trị được mã hóa được trả lại cho trình duyệt của khách hàng. Sau đó, api json sẽ sử dụng cookie đó để xác thực danh tính của người gọi.

Cách tiếp cận này rõ ràng là yêu cầu sử dụng cookie, do đó có thể hoặc không có vấn đề gì với bạn.

0

Rất tiếc, không có DRM trên web :-)

Bạn không thể coi HTML là ứng dụng khách đáng tin cậy. Đó là một tập lệnh văn bản thuần túy được giải thích trên máy tính của người khác khi họ thấy phù hợp. Dù bạn cho phép mã JavaScript "của riêng bạn" cho phép bất kỳ ai. Bạn thậm chí không thể xác định khoảng thời gian đó là "của bạn" với số GreasemonkeyFirebug trong tự nhiên.

Bạn phải sao chép tất cả các điều khiển truy cập và hạn chế logic nghiệp vụ trong máy chủ như thể không có điều nào trong số đó có mặt trong ứng dụng JavaScript của bạn.

Bao gồm dịch vụ trong SSO của bạn, hạn chế các URL mà mỗi người dùng có quyền truy cập, thiết kế dịch vụ giữ cho khách hàng nhớ, không phải mã JavaScript của bạn.

+0

Ồ, và khi nào mọi người bắt đầu sử dụng dịch vụ của bạn theo những cách HTML của bạn không cho phép? Đi theo lời khuyên phát triển kinh doanh miễn phí và cuộn với nó! – Szocske

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