web-dev-qa-db-ja.com

Retrofitが302を自動的にフォローしないようにするにはどうすればよいですか

AndroidでRetrofitを使用して発信しようとしている認証呼び出しがあります。呼び出しは、302を成功ページまたは失敗ページのいずれかに返します。元の302応答は、成功時に認証を維持するために必要なセッションCookieを返しますが、Retrofitは、Cookieを消費する機会を得る前に、リダイレクトURLに要求を自動的に渡します。

リダイレクトに従わないようにする方法はありますか?または、2番目の呼び出しを行う前に適切なヘッダーを追加できるRetrofitで応答ハンドラーを作成する方法はありますか?

17
nak5ive

リダイレクトを防ぐには、たとえばOkHttp2を使用してクライアントを構成する必要があります。

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からこれを読むことができます answer ):

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

投稿が非常に古い場合のイベント、OkHttp3での私の答えは次のようにビルダーを使用してください

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

responseオブジェクト(私は実際にRetrofitを使用しています)に、リダイレクトURLがあります。

response.headers.get("Location")

お役に立てれば

6
gropapa

私はこれが古い投稿であることを知っています、多分それはまだ誰かのために役立つでしょう。同様の問題があります。私の解決策は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にアクセスできます。クッキーデータは自動的に追加されたと思います。たぶん、あなたはあなたの特別なニーズを渡すためにgetRedirect()、isRedirected()関数を書き直す必要があります。

2
vivitacsovi

私はあなたと同じような状況にありました。基本的に必要なのは、リダイレクトする前にサーバーが返す「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());
}
0
VM4

ログインRESTAPIを呼び出すときにPOST/PUTを使用している可能性が高く、OkHttpが非GETまたはHEADリクエストをリダイレクトする前にGETリクエストに変換するため、以前の回答を編集しました。おそらくあなたのために働くことはありません。

現在、リダイレクトを無効にする機能はOkHttpにありませんが、プルリクエストを送信しました。そのプルリクエストが受け入れられた場合は、リダイレクトを無効にして、当面はこのユースケースに自分で対処する機会を与える必要があります。

プルリクエストは次のとおりです https://github.com/square/okhttp/pull/944

0
Miguel Lavigne