2012-04-14 30 views
14

Tôi đang triển khai trình bao bọc R xung quanh PiCloud's REST API bằng cách sử dụng gói RCurl để yêu cầu HTTP (S) đối với máy chủ API. API sử dụng xác thực HTTP cơ bản để xác minh rằng người dùng có đủ quyền. Tài liệu PiCloud đưa ra ví dụ về cách sử dụng api và xác thực bằng curl:RCurl: Xác thực HTTP Khi trang web phản hồi với mã HTTP 401 Nếu không có WWW-Authenticate

$ curl -u 'key:secret_key' https://api.picloud.com/job/?jids=12 

Điều này hoạt động hoàn hảo. Dịch này để chỉ huy một RCurl tương đương của:

getURL("https://api.picloud.com/job/?jids=12", userpwd="key:secret") 

Thực thi chức năng này, tôi nhận được thông báo lỗi sau:

[1] "{\"error\": {\"msg\": \"No HTTP Authorization information present\", \"code\": 995, \"retry\": false}}" 

Khám phá vấn đề này sâu hơn tôi thấy rằng các yêu cầu HTTP thực hiện bởi các lệnh curl bao gồm trường ủy quyền trong lệnh GET đầu tiên.

RCurl không thực hiện việc này. Thay vào đó, trước tiên nó sẽ gửi một yêu cầu GET mà không cần thiết lập trường ủy quyền. Nếu nó nhận được mã lỗi 401 và một đáp ứng với trường WWW-Authenticate, nó sẽ gửi một yêu cầu GET khác với trường Authorization.

Mặc dù thông số HTTP yêu cầu thư trả lại bằng mã lỗi 401 để bao gồm trường WWW-Authenticate trường thông báo API PiCloud thì không. Vì vậy, khi gọi getURL ngay cả với tùy chọn userpwd, RCurl sẽ không bao giờ gửi yêu cầu GET với bộ trường ủy quyền. Kết quả là xác thực sẽ luôn thất bại.

Có cách nào để buộc RCurl thiết lập trường Cấp phép trong thông báo GET đầu tiên mà nó gửi không? Nếu không có bất kỳ gói R nào khác mà tôi có thể xem xét sử dụng?

Trả lời

23

Tôi đã giải quyết được sự cố với sự trợ giúp của tác giả của RCurl, Duncan Lang. Giải pháp là đặt rõ ràng tùy chọn httpauth đặt phương thức xác thực để thử ban đầu. Công trình này:

getURL("https://api.picloud.com/job/?jids=12", userpwd="key:secret", httpauth = 1L) 

httpauth là một bitmask chỉ định phương pháp xác thực để sử dụng. Xem phần Xác thực HTTP của the libcurl tutorial để biết thêm chi tiết.

+1

Tôi đã cố gắng để theo dõi này xuống trong nhiều giờ. Cảm ơn! –

+0

Nếu đi qua trong một tay cầm curl có thể sử dụng lại, bạn phải đặt 'httpauth = 1' trong cuộc gọi của bạn thành' getCurlHandle() '. (Đây là cách duy nhất tôi có thể nhận được 'postForm()' để làm việc với auth cơ bản: chuyển 'httpauth' thành tham số' postForm() 'không hoạt động.) –

6

Mã tương đương trong httr là:

library(httr) 
GET("https://api.picloud.com/job/?jids=12", authenticate("key", "secret")) 
Các vấn đề liên quan