2012-04-14 7 views
14

Ich implementiere einen R-Wrapper um PiCloud's REST API mit dem RCurl-Paket, um HTTP (S) -Anforderungen an den API-Server zu stellen. Die API verwendet die einfache HTTP-Authentifizierung, um zu überprüfen, ob die Benutzer über ausreichende Berechtigungen verfügen. Die PiCloud-Dokumentation gibt ein Beispiel für die Verwendung der API und die Authentifizierung mit Curl:RCurl: HTTP-Authentifizierung, wenn Website mit HTTP 401 Code ohne WWW-Authenticate reagiert

Dies funktioniert perfekt. Die Umsetzung dieser an ein Befehl des äquivalenten RCurl:

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

Ausführen dieser Funktion I die folgende Fehlermeldung:

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

Explo das Problem in mehr Tiefe fand ich, dass die HTTP-Anforderungen von der curl Befehl gemacht enthalten das Autorisierungsfeld im ersten GET-Befehl.

RCurl tut dies nicht. Stattdessen sendet es zuerst eine GET-Anfrage ohne das Berechtigungsfeld. Wenn es einen 401-Fehlercode und eine Antwort mit einem WWW-Authenticate-Feld empfängt, sendet es eine weitere GET-Anfrage mit dem Berechtigungsfeld.

Obwohl die HTTP-Spezifikation Nachrichten erfordert, die mit einem 401-Fehlercode zurückgegeben werden, um die WWW-Authenticate-Feld-PiCloud-API-Nachrichten nicht aufzunehmen. Daher wird RCurl beim Aufruf von getURL selbst mit dem Optionssatz userpwd niemals eine GET-Anfrage mit dem eingestellten Berechtigungsfeld senden. Daher wird die Authentifizierung immer fehlschlagen.

Gibt es eine Möglichkeit, RCurl zu zwingen, das Autorisierungsfeld in der ersten GET-Nachricht zu setzen, die es sendet? Wenn nicht, gibt es noch andere R-Pakete, in denen ich nachsehen könnte?

Antwort

23

Ich habe das Problem mit Hilfe des Autors von RCurl, Duncan Lang gelöst. Die Lösung besteht darin, explizit die HTTPAUTH-Option festzulegen, mit der die Authentifizierungsmethode zunächst festgelegt wird. Dies funktioniert:

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

httpauth ist eine Bitmaske, die angibt, welche Authentifizierungsmethoden verwendet werden sollen. Weitere Informationen finden Sie im Abschnitt HTTP-Authentifizierung unter the libcurl tutorial.

+1

Ich habe dies stundenlang nach unten versucht, zu verfolgen. Vielen Dank! –

+0

Wenn Sie ein wiederverwendbares Curl-Handle übergeben, müssen Sie in Ihrem Aufruf von 'getCurlHandle()' 'httpauth = 1' setzen. (Dies war der einzige Weg, wie ich 'postForm() 'mit Basic Auth arbeiten konnte: die Übergabe von' httpauth' als Parameter an 'postForm()' funktionierte nicht.) –

6

Der entsprechende Code in HTTR ist:

library(httr) 
GET("https://api.picloud.com/job/?jids=12", authenticate("key", "secret")) 
Verwandte Themen