Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18

    [DELPHI] Client Rest : Bad Request nel tentativo di richiesta di autenticazione ad un webservice rest

    Salve a tutti.
    Premessa: Devo realizzare un client rest per fruire di alcuni servizi di un webservice restful.
    Il webservice prevede che il client si autentifichi con le credenziali corrette per fornirgli un valido Access Token (secondo lo standard OAuth 2.0). Il guaio è che il server mi dà sempre in risposta l'errore HTTP/1.1 400 Bad request.
    Molto probailmente c'è qualcosa di errato nel sorgente.. Allego il codice delphi che mi dà problemi ed anche quello PHP dal quale ho preso "spunto" (che invece è funzionante e mi restituisce un token valido!).
    Qualcuno ha esperienza in merito con la classe TIdHttp? Grazie.

    Delphi (le costanti sono in maiuscolo):

    codice:
      Response:= TMemoryStream.Create;
      EncodedCredit:= EncodeBase64(CLIENT_ID + ':' + CLIENT_SECRET); 
      ClientCredentials:='grant_type=password&username='+USER+'&password='+PASSWORD+'&client_id='+CLIENT_ID+'&client_secret='+CLIENT_SECRET;
    
      IdHttp:=TIdHttp.Create(nil);
      try
        //Headers
        IdHttp.Request.CustomHeaders.Add('Authorization: Basic '+EncodedCredit);
        IdHttp.Request.ContentLength := Length(ClientCredentials);
        IdHttp.Request.Accept:='application/json';
        IdHttp.Request.Method:='Post';
    
      
        //use SSL
        IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
        IdHttp.IoHandler:=IdSSLIOHandlerSocket1;
        IdSSLIOHandlerSocket1.SSLOptions.VerifyMode := [];
        
        try
          PostStream:=TStringStream.Create(ClientCredentials);
          try
             PostStream.Position:=0;
             Res:=IdHttp.Post(TokenEndPoint,PostStream);  //mi ritorna errore 400
          finally
             PostStream.Free;
          end;
        except
            On E:Exception do begin
              Res:=E.Message;
            end;
        end;
    
      finally
        FreeAndNil(Response);
        IdHttp.Free;
      end;
    end;

    PHP sorgente funzionante:

    codice:
     $curl = curl_init();
     curl_setopt($curl, CURLOPT_URL, $TokenEndPoint);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
     curl_setopt($curl, CURLOPT_POST, 1);
    
     $body = "grant_type=password&username=".$login."&password=".$password."&client_id=".$this->clientId."&client_secret=".$this->clientSecret;
            
     $headers = array();
     $headers["Content-length"] = strlen($body);
     $headers["Accept"] = "application/json";
     $headers["Authorization"] = "Basic ".base64_encode($this->clientId.":".$this->clientSecret);
                
     $curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
     $curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
    
     $result = curl_exec($curl);
     $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
     curl_close($curl);
    Ultima modifica di LeleFT; 18-02-2014 a 15:25 Motivo: Aggiunti i tag CODE

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    E' molto difficile rispondere senza poter verificare passo per passo la costruzione della richiesta da inviare al server.

    Inoltre, c'è anche l'uso del TIdSSLIOHandlerSocketOpenSSL di mezzo che complica ulteriormente le cose.

    Innanzitutto, verificherei che i dati "postati" al server dalla versione Delphi siano gli stessi di quella PHP, in particolare il valore ottenuto dall'encoding in base 64, andando in debug su entrambe le soluzioni (o mostrando in qualche modo a video i valori).

    Per esperienza personale, il protocollo OAuth può dare parecchi mal di pancia...
    Quando avrò un attimo di tempo, controllerò meglio il codice che hai scritto.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18
    Ciao alka.
    Ho controllato il valore di EncodedCredit calcolato come EncodeBase64(CLIENT_ID + ':' + CLIENT_SECRET).
    Dato che nella versione in PHP il post mi funziona, ho pensato di debuggare il risultato della funzione base64_encode($this->clientId.":".$this->clientSecret) e di passare la stringa ottenuta direttamente nella variabile stringa EncodedCredit di delphi. Ottengo però la medesima risposta 400: bad request
    Hai qualche altro suggerimento?

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18
    Salve Alka.
    Buone notizie. Ho risolto il problema ricontrollando bene i dati passati nel post ed aggiungendo il contenttype corretto:IdHttp1.Request.ContentType:='application/x-www-form-urlencoded'.

    Ora il server rest mi ritorna correttamente il token per fruire dei suoi servizi.

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    Grazie davvero per il tuo feedback, che potrà essere senz'altro utile a chiunque si troverà a fronteggiare un problema analogo.

    Mi scuso ancora per non aver trovato purtroppo il tempo di approfondire la questione, ma sono contento che tu abbia risolto.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.