Ho testato le mie api con curl e funziona tutto, ora le devo utilizzare
con un'applicazione rails ed utilizzo la gemma in oggetto con la quale
però ho qualche problema con la richiesta put (e delete solo che di
questo non ricordo i dettagli). Get e post funzionano, col metodo
put non vengono utilizzati i parametri forniti alla chiamata:
@clnt = HTTPClient.new
res = @clnt.put("http://localhost:3001/api/v1/pippe/#{options[:id]}",
{:auth_token => @auth_token}.merge(options[:dati]))
i parametri vengono passati ma è come se put non li utilizzasse, non
arriva il token e giustamente ritorna un 401
Started PUT "/api/v1/pippe/2" for 127.0.0.1 at Wed Jun 27 17:31:23 +0200
2012
Processing by Api::V1::PippeController#update as JSON
Parameters: {"id"=>"2"}
WARNING: Can't verify CSRF token authenticity
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" =
1 LIMIT 1
(0.0ms) begin transaction
(0.0ms) commit transaction
Completed 401 Unauthorized in 4ms
non ho spulciato il codice ma apparentemente sembra simile:
# File 'lib/httpclient.rb', line 595
def post(uri, body = '', extheader = {}, &block)
request(:post, uri, nil, body, extheader, &block)
end
# File 'lib/httpclient.rb', line 600
def put(uri, body = '', extheader = {}, &block)
request(:put, uri, nil, body, extheader, &block)
end
Qualcuno ha qualche idea?
on 2012-06-27 17:53
on 2012-06-27 18:36
E' un baco di HTTPClient:
#lib\httpclient.rb
#ho modificato il metodo create_request (riga 965)
aggiungendo questo codice:
elsif ['DELETE', 'PUT'].include? method
header << ['Content-Type', 'application/x-www-form-urlencoded']
ora i parametri vengono passati.
Non so se è un problema noto, io non ho trovato nulla. In questi casi si
avvisa l'autore o si crea una patch? (non sono molto pratico)
Comunque ho risolto, ciao
on 2012-06-27 18:49
Dando un veloce sguardo alla libreria che hai usato, ci sono due
problemi
con la tua soluzione:
1. HTTPClient non accetta body per le chiamate DELETE (quindi
quell'header
inutile e potenzialmente errato)
# Sends DELETE request to the specified URL. See request for
arguments.
def delete(uri, *args, &block)
request(:delete, uri, argument_to_hash(args, :header), &block)
end
2. Secondo l'implementazione, l'ordine dei parametri uri, body, header
# Sends PUT request to the specified URL. See request for arguments.
def put(uri, *args, &block)
request(:put, uri, argument_to_hash(args, :body, :header), &block)
end
Nel codice tu fai il merge del body con gli header e li passi come primo
parametro. Questo mi fa pensare che l'errore stia nel tuo uso di
HTTPClient. L'output della console pare essere d'accordo
*WARNING: Can't verify CSRF token authenticity*
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" =
1 LIMIT 1
(0.0ms) begin transaction
(0.0ms) commit transaction
*Completed 401 Unauthorized in 4ms*
Apparentemente, la tua richiesta non viene mai eseguita poich quella
chiamata bloccata dall'autenticazione. Sono propenso a pensare che il
bug
non sia in HTTPClient ma nella tua chiamata.
-- Simone
2012/6/27 Marco Mastrodonato <m.mastrodonato@gmail.com>
> Non so se un problema noto, io non ho trovato nulla. In questi casi si
>
--
Simone Carletti
Application Developer
Site & Blog: http://www.simonecarletti.com/
LinkedIn: http://linkedin.com/in/weppos
Skype: weppos
on 2012-06-27 19:15
Ciao Simone, in effetti ho dovuto modificare anche la chiamata del
delete:
def delete(uri, *args, &block)
request(:delete, uri, argument_to_hash(args, :body, :header),
&block)
end
...non ho capito perchè non è stato previsto il body.
Il warning l'avevo notato ma non ho capito chi lo generava.
Ho usato la documentazione di HTTPClient anche se non è proprio
aggiornatissima, indica l'ordine che ho usato io.
Ora devo scappare, domani controllo meglio, grazie comunque
on 2012-06-27 19:28
2012/6/27 Marco Mastrodonato <m.mastrodonato@gmail.com> > ...non ho capito perch non stato previsto il body. Le specifiche HTTP 1.0 n lo vietano n lo consentono. Non saprei le 1.1. Di norma viene omesso (la maggior parte dei server HTTP lo ignora). Mi viene da chiedere a cosa ti serva un body per cancellare una risorsa. Quali parametri hai necessit di passare? -- Simone Carletti Application Developer Site & Blog: http://www.simonecarletti.com/ LinkedIn: http://linkedin.com/in/weppos Skype: weppos
on 2012-06-28 09:44
Per utilizzare l'api è necessario fornire il token di autenticazione: il parametro che devo allegare a tutte le chiamate compresa la delete.
on 2012-06-28 09:53
Non necessario. Se vai a vedere il sorgente del modulo RequestForgeryProtection<https://github.com/rails/rails/blob/3-2-stable/act..., nello specifico il metodo verify_authenticity_token<https://github.com/rails/rails/blob/3-2-stable/act... noterai che dipende dal controllo def verified_request? !protect_against_forgery? || request.get? || form_authenticity_token == params[request_forgery_protection_token] || form_authenticity_token == request.headers['X-CSRF-Token'] end verified_request? ritorna true (quindi autorizza l'esecuzione) in diversi casi, compreso nel caso in cui l'header http X-CSRF-Token sia presente e corrisponda al token. In altre parole, sufficiente nelle tue chiamate API passare il token come header HTTP per autorizzare la chiamata all'API, non serve simulare il passaggio via parametro. Quindi, almeno nel caso della DELETE, non ti serve body. -- Simone 2012/6/28 Marco Mastrodonato <m.mastrodonato@gmail.com> > Per utilizzare l'api necessario fornire il token di autenticazione: il > parametro che devo allegare a tutte le chiamate compresa la delete. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Ml mailing list > Ml@lists.ruby-it.org > http://lists.ruby-it.org/mailman/listinfo/ml > -- Simone Carletti Application Developer Site & Blog: http://www.simonecarletti.com/ LinkedIn: http://linkedin.com/in/weppos Skype: weppos
on 2012-06-28 10:45
Grazie, stavo diventando matto a trovare quel warning! Comunque non devo passare il token di rails ma quello per l'autenticazione in devise.
on 2012-06-28 10:56
Sono quasi sicuro che anche devise accetti authenticazione via header o querystring. :) 2012/6/28 Marco Mastrodonato <m.mastrodonato@gmail.com> > -- Simone Carletti Application Developer Site & Blog: http://www.simonecarletti.com/ LinkedIn: http://linkedin.com/in/weppos Skype: weppos
on 2012-06-28 12:38
Simone, ho letto il tuo blog e ti ho mandato una mail, l'indirizzo con .name finale
on 2012-07-16 16:24
Devise salva il token in un cookie che utilizza in automatico per cui è
sufficiente il login dell'api e non serve più quindi passarlo come
parametro. Con questa soluzione però deve essere fornita user e password
per il login:
@clnt.post("#{@server}/api/users/sign_in", {"user_login[email]" =>
@user_login, "user_login[password]" => password})
E' un alternativa ma forse preferivo la precedente dove bastava fornire
il token.
Comunque, stavo provando ad accedere con token nell'header seguendo gli
esempi della documentazione:
https://github.com/nahi/httpclient/blob/master/sam...
puts clnt.get(target, nil, { "auth_token" => "eFRv9Jh5j6dzVxLxjQ6D"
}).content
ma la chiamata è priva di quell'header ed infatti non funziona. Sto
cercando di capire se sbaglio qualcosa, la sequenza di parametri della
get coincide con l'esempio:
def get(uri, *args, &block)
request(:get, uri, argument_to_hash(args, :query, :header,
:follow_redirect), &block)
end
on 2012-07-17 14:19
Sembra che devise che non supporti l'autenticazione con token su header, non ho indagato molto, ho risolto così: https://gist.github.com/3129118
on 2012-07-19 09:23
Giusto per completare il quadro, quà si parla di devise e token su header: https://groups.google.com/forum/?fromgroups#!topic...
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.