18

我尝试在 Android 上使用 Retrofit 进行身份验证调用。该调用将 302 返回到成功或失败页面。最初的 302 响应带回了一个会话 cookie,它需要在成功时维护身份验证,但是在我有机会使用 cookie 之前,Retrofit 会自动将请求交给重定向 url。

有没有办法防止跟随重定向?或者有没有办法在 Retrofit 上编写一个响应处理程序,可以在进行第二次调用之前添加适当的标头?

4

5 回答 5

15

为了防止重定向,您必须配置您的客户端,例如使用 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();
于 2015-03-22T15:05:33.630 回答
6

事件如果帖子很旧,这是我对 OkHttp 3 的回答,只需使用以下构建器

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

在 Response 对象中(我实际上使用 Retrofit),你会在

response.headers.get("Location")

希望这可以帮助

于 2016-02-02T22:45:39.693 回答
2

我知道这是一个旧帖子,也许它仍然会对某人有所帮助。我有一个类似的问题,我的解决方案是向 httpClient添加一个重定向策略( http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/RedirectStrategy.html ):

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();

有了这个,我可以访问任何(私人)网址。我认为cookie数据是自动添加的。也许您应该重写 getRedirect()、isRedirected() 函数来满足您的特殊需求。

于 2015-03-19T09:52:29.250 回答
0

我和你的情况类似。基本上我们只需要在重定向之前捕获服务器返回的“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());
}
于 2014-06-12T14:36:03.920 回答
0

我已经编辑了我之前的答案,因为您很可能在调用登录休息 api 时使用 POST/PUT,并且 OkHttp 在重定向之前将任何非 GET 或 HEAD 请求转换为 GET 请求,这可能对您不起作用。

目前,OkHttp 缺少禁用重定向的功能,但我已经提交了一个拉取请求。如果并且当该拉取请求被接受时,它应该允许您禁用重定向,让您有机会暂时自行处理此用例。

这是拉取请求https://github.com/square/okhttp/pull/944

于 2014-06-17T15:21:40.903 回答