2014-06-09 11 views
11

Ho una chiamata di autenticazione che sto cercando di utilizzare Retrofit su Android. La chiamata restituisce un 302 a una pagina di successo o di fallimento. La risposta originale 302 riporta un cookie di sessione necessario per mantenere l'autenticazione in caso di successo, tuttavia Retrofit inoltra automaticamente la richiesta all'URL di reindirizzamento prima che io abbia la possibilità di consumare il cookie.Come si impedisce a Retrofit di seguire automaticamente un 302

C'è un modo per impedire di seguire il reindirizzamento? O c'è un modo per scrivere un gestore di risposta su Retrofit che può aggiungere l'intestazione appropriata prima di effettuare la seconda chiamata?

risposta

0

Ero in una situazione simile alla tua. Fondamentalmente tutto ciò di cui abbiamo bisogno è catturare l'intestazione "Set-Cookie" che il tuo server restituisce prima del reindirizzamento. Ecco come ho gestito utilizzando OkHTTP:

final OkHttpClient client = new OkHttpClient(); 
CookieHandler handler = client.getCookieHandler(); 
CookieManager manager = new CookieManager(); 
handler.setDefault(manager); 

//boilerplate: 
RequestBody formData = new FormEncodingBuilder() 
     .add("req_username", username) 
     .add("req_password", password).build(); 
Request request = new Request.Builder().url(LOGIN_URL).post(formData).build(); 
Response response = client.newCall(request).execute(); 
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

// print our cookies: 
List <HttpCookie> cookies = manager.getCookieStore().getCookies(); 
for(HttpCookie cookie : cookies) { 
    Log.v(TAG, cookie.getName() + "=" + cookie.getValue()); 
} 
0

Ho modificato la mia risposta precedente in quanto si sta molto probabilmente utilizzando un POST/PUT quando si chiama il tuo login API REST e OkHttp converte tutto non richiesta GET o HEAD in una richiesta GET prima del reindirizzamento che probabilmente non avrebbe funzionato per te.

Attualmente la funzione di disabilitazione dei reindirizzamenti manca a OkHttp ma ho inviato una richiesta di estrazione per questo. Se e quando tale richiesta di pull viene accettata, dovrebbe consentire all'utente di disabilitare il reindirizzamento dandoti l'opportunità di gestire questo caso d'uso per il momento.

Ecco la richiesta di pull https://github.com/square/okhttp/pull/944

2

So che questo è un vecchio post, forse sarà ancora aiutare qualcuno. Ho un problema simile, la mia soluzione era quella di aggiungere un redirectStrategy (http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/RedirectStrategy.html) per HttpClient:

private static final RestAdapter REST_ADAPTER= new RestAdapter.Builder() 
      .setEndpoint(HTTP_TEST_URL) 
      .setClient(new ApacheClient(HttpClients.custom() 
       .setRedirectStrategy(new RedirectStrategy() { 
        @Override 
        public boolean isRedirected(HttpRequest request, HttpResponse response, 
         HttpContext context) throws ProtocolException { 
         return response.getStatusLine().getStatusCode() == 302; 
        } 

        @Override 
        public HttpUriRequest getRedirect(HttpRequest request, 
         HttpResponse response, HttpContext context) 
         throws ProtocolException { 

         //String cookieValue = response.getFirstHeader("Set-Cookie").getValue(); 
         String location = response.getFirstHeader("location").getValue(); 

         HttpUriRequest request_= new HttpGet(location); 
         return request_; 
        }}).build())) 
      .build(); 

Con questo posso ottenere l'accesso a qualsiasi URL (privato). Penso che i dati dei cookie siano aggiunti automaticamente. Forse dovresti riscrivere le funzioni getRedirect(), isRedirected() per soddisfare le tue esigenze speciali.

+0

e ricordarsi di aggiungere la dipendenza giusto per la vostra applicazione: https: // hc .apache.org/httpcomponents-client-4.3.x/android-port.html. –

6

per evitare che il reindirizzamento è necessario configurare il client, ad esempio con OkHttp 2:

private sendRequest() { 
    OkHttpClient client = new OkHttpClient(); 
    client.setFollowRedirects(false); 

    connectAdapter = new RestAdapter.Builder() 
      .setClient(new OkClient(client)) 
      .setEndpoint("http://yourendpoint") 
      .setLogLevel(RestAdapter.LogLevel.FULL) 
      .build(); 

    connectAdapter.create(YourRequest.class).sendMyRequest("login","password"); 

} 

Con OKHTTP 3 (si può leggere questo answer da @gropapa):

OkHttpClient.Builder builder = new OkHttpClient.Builder(); 
builder.followRedirects(false); 
OkHttpClient httpClient = builder.build(); 
+1

Ciò causa il retrofit per generare un errore, piuttosto che restituire una risposta che ha un 303. È il comportamento previsto? –

+0

Non lo so, nel mio caso il problema era un reindirizzamento che si è verificato in cima a un 302. Nessun errore è stato lanciato. Che tipo di errore viene corretto dal retrofit nel tuo caso? – Climbatize

+0

Ehi, non so se è ancora pertinente, ma puoi aggiungere un try catch arround e leggere la risposta dall'eccezione.Semina fino a quando non c'è un altro modo per non seguire i reindirizzamenti, ma continuando a leggere la risposta puoi farlo con il comando try. – neristance

2

evento se il post è MOLTO vecchio, ecco la mia risposta con OkHttp 3 basta usare il builder come segue

OkHttpClient.Builder builder = new OkHttpClient.Builder(); 
builder.followRedirects(false); 
OkHttpClient httpClient = builder.build(); 

in un oggetto Response (io uso Retrofit in realtà), troverete l'URL di reindirizzamento in

response.headers.get("Location") 

Spero che questo aiuti

Problemi correlati