Как предотвратить автоматическое восстановление Retrofit после 302

У меня есть аутентификационный вызов, который я пытаюсь сделать с помощью Retrofit на Android. Вызов возвращает 302 на страницу успеха или сбоя. Исходный ответ 302 возвращает куки файлы сеанса, необходимые для обеспечения аутентификации при успешном завершении, однако Retrofit автоматически передает запрос на URL-адрес перенаправления, прежде чем я получаю возможность использовать cookie.

Есть ли способ предотвратить перенаправление? Или есть способ написать обработчик ответа на Retrofit, который может добавить соответствующий заголовок перед тем, как сделать второй вызов?

Ответ 1

чтобы предотвратить перенаправление, которую вы должны настроить для своего клиента, например, с помощью 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");

}

С помощью OKHTTP 3 (вы можете прочитать этот ответ от @gropapa):

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

Ответ 2

Событие, если сообщение ОЧЕНЬ старое, вот мой ответ с OkHttp 3 просто используйте строитель в качестве следующего

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

в объекте Response (на самом деле я использую Retrofit), вы найдете URL-адрес перенаправления в

response.headers.get("Location")

Надеюсь, что это поможет

Ответ 3

Я знаю, что это старый пост, возможно, он все равно поможет кому-то. У меня есть аналогичная проблема, я решил добавить redirectStrategy (http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/RedirectStrategy.html) в 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();

С этим я могу получить доступ к любому (частному) URL-адресу. Я думаю, что данные cookie добавляются автоматически. Возможно, вам нужно переписать функции getRedirect(), isRedirected(), чтобы передать ваши особые потребности.

Ответ 4

Я был в похожей ситуации с твоей. В основном все, что нам нужно, это захватить заголовок "Set-Cookie", который ваш сервер возвращает перед перенаправлением. Так я обработал его с помощью 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());
}

Ответ 5

Я отредактировал свой предыдущий ответ, так как вы, скорее всего, используете POST/PUT при вызове вашего имени для входа в систему api, и OkHttp конвертирует любой запрос без GET или HEAD в запрос GET перед перенаправлением, которое, вероятно, не сработает для вас.

В настоящее время функция отключения перенаправления отсутствует в OkHttp, но я отправил запрос на перенос. Если и когда этот запрос на перенос принят, он должен позволить вам отключить перенаправление, давая вам возможность использовать этот вариант использования самостоятельно на время.

Здесь запрос на растяжение https://github.com/square/okhttp/pull/944