【问题标题】:Add cookies to retrofit 2 request添加 cookie 以改造 2 请求
【发布时间】:2016-11-20 00:05:34
【问题描述】:

我需要使用改造 2.0 添加 cookie。如果我理解正确,cookies - 与标题相同。必须添加此 cookie:

private HashMap<String, String> cookies = new HashMap();
cookies.put("sessionid", "sessionId");
cookies.put("token", "token");

这个与 Jsoup 库一起工作:

String json = Jsoup.connect(apiURL + "/link")
                    .cookies(cookies)
                    .ignoreHttpErrors(true)
                    .ignoreContentType(true)
                    .execute()
                    .body();

这是我的改造请求代码:

@GET("link")
Call<CbGet> getData(@Header("sessionid") String sessionId, @Header("token") String token);

但它不起作用...... 我得到 403 错误代码,所以请求中没有 cookie...

有什么想法吗?

【问题讨论】:

标签: android cookies retrofit retrofit2


【解决方案1】:

首先:cookie 与 header 不同。 Cookie 是一个名为 Cookie 的特殊 HTTP 标头,后跟键和值对的列表(用“;”分隔)。比如:

Cookie: sessionid=sessionid; token=token

由于you cannot set multiple Cookie headers in the same request,您不能对单独的值使用两个@Header 注释(示例中的sessionidtoken)。我能想到一个非常老套的解决方法:

@GET("link")
Call<CbGet> getData(@Header("Cookie") String sessionIdAndToken);

您更改方法以在一个字符串中发送 sessionId 和令牌。因此,在这种情况下,您应该事先手动生成 cookie 字符串。在你的情况下 sessionIdAndToken 字符串对象应该等于 "sessionid=here_goes_sessionid; token=here_goes_token"

正确的解决方案是通过添加 OkHttp(即 Retrofit 用于进行底层 http 调用的库)request interceptor 来设置 cookie。您可以查看解决方案或添加自定义标头here

【讨论】:

    【解决方案2】:

    为什么不使用 cookieJar 选项?

    new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(
            new OkHttpClient().newBuilder()
                .cookieJar(new SessionCookieJar()).build())
        .build();
    
    private static class SessionCookieJar implements CookieJar {
    
        private List<Cookie> cookies;
    
        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            if (url.encodedPath().endsWith("login")) {
                this.cookies = new ArrayList<>(cookies);
            }
        }
    
    
        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            if (!url.encodedPath().endsWith("login") && cookies != null) {
                return cookies;
            }
            return Collections.emptyList();
        }
    }
    

    【讨论】:

    • 可能你忘了在saveFromResponse方法中添加:this.cookies.addAll(cookies);
    • 没有。您不想添加到 cookie 中。您可能希望完全重置 saveFromResponse 中的 cookie。
    【解决方案3】:

    API Web 服务示例添加 Header

    @FormUrlEncoded
    @POST("getDriverRoutes")
    Call<Guzergah> getGuzergah(@Header("Cookie") String userCookie, @Field("driver_id") int driver_id);
    

    当您登录系统时,将 cookie 保存到您的本地响应中

     public void onResponse(Response<Login> response, Retrofit retrofit) {
                hidepDialog();
                String cookie = response.headers().get("Set-Cookie");
                editor.putString("user_cookie", cookie.split(";")[0]);
                editor.commit();
    

    在您需要自动化的每项服务中发送您的 cookie,从 sharepreference 中获取并与您的网络服务一起发送

      String userCookie = shp.getString("user_cookie", ""); // here is cookies before send
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://server.aracadabra.com:8080/").
                        addConverterFactory(GsonConverterFactory.create())
                .build();
    
        final APIService service = retrofit.create(APIService.class);
    
        final Call<SenMsgStatus> loginMCall = service.sendMessage(userCookie, type, route_id, user_id, passenger_id, passenger_status, text);
    

    【讨论】:

      【解决方案4】:

      要将 cookie 标头添加到 okhttp 请求标头中,请在 Interceptor 中添加:

      request= request.newBuilder().addHeader("Cookie", sessionIdAndToken).build();

      Ref:https://github.com/square/okhttp/wiki/Interceptors@Alexander Mironov 提到的

      此处的完整示例代码:希望对您有所帮助

      import okhttp3.Interceptor;
      import okhttp3.Request;
      import okhttp3.Response;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import java.io.IOException;
      import java.util.List;
      
      
      public class LoggingInterceptor implements Interceptor {
      
          private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
          @Override
          public Response intercept(Interceptor.Chain chain) throws IOException {
              Request request = chain.request();
      
              long t1 = System.nanoTime();
              request = processRequest(request);
              logger.info("Sending request with url:{} and connection status:{} and request headers:{}",
                      request.url(), chain.connection(), request.headers());
      
              Response response = chain.proceed(request);
              long t2 = System.nanoTime();
              logger.info("Received response for url:{} and time taken:{} and response headers as:{}",
                      response.request().url(), (t2 - t1) / 1e6d, response.headers());
      
              response = processResponse(response);
              return response;
          }
          //Add cookies for all subsequent requests
          private Request processRequest(Request request) {
              if(!request.url().toString().contains("/v1/authorize")) {
                  final EmployeeSession session = getSession();
                  StringBuilder etokenAndUId = new StringBuilder("etoken=");
                  etokenAndUId.append(session.getEtoken()).append(";").append("uId=").append(session.getUId());
                  logger.info("inside processRequest for all subsequent requests, sending cookies as etokenAndUId values:{}", etokenAndUId.toString());
                  request= request.newBuilder().addHeader("Cookie", etokenAndUId.toString()).build();
              }
              return request;
          }
      
          //Extract cookies from login url
          private Response processResponse(Response response) {
              if(response.request().url().toString().contains("/v1/authorize")) {
                  final List<String> cookieHeaders = response.headers("Set-Cookie");
                  String etoken = "", uId = "";
                  for (String cookieHeader : cookieHeaders) {
                      if(cookieHeader.contains("etoken=")) {
                          etoken = cookieHeader.substring(7, cookieHeader.indexOf(';'));
                      }
                      else if(cookieHeader.contains("uId=")) {
                          uId = cookieHeader.substring(4, cookieHeader.indexOf(';'));
                      }
                  }
                  logger.info("inside processResponse found cookies from login url response: etoken:{} and uid:{}", etoken, uId);
                  setSession(etoken, uId, "c1");
                  logger.info("current employee session:{}", getSession());
              }
              return response;
          }
       }    
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        相关资源
        最近更新 更多