Add cookies to retrofit 2 request

前端 未结 4 1509
生来不讨喜
生来不讨喜 2020-12-30 00:53

I need to add cookies with retrofit 2.0. If i understand correct, cookies - the same as headers. this cookies must be added:

private HashMap

        
相关标签:
4条回答
  • 2020-12-30 01:03

    First of all: cookie is not the same as a header. Cookie is a special HTTP header named Cookie followed by list of the pairs of keys and values (separated by ";"). Something like:

    Cookie: sessionid=sessionid; token=token
    

    Since you cannot set multiple Cookie headers in the same request you are not able to use two @Header annotations for separate values (sessionid and token in your sample). I can think of one very hacky workaround:

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

    You change your method to send sessionId and token in one string. So in this case you should manually generate cookie string beforehand. In your case sessionIdAndToken String object should be equal to "sessionid=here_goes_sessionid; token=here_goes_token"

    The proper solution is to set cookies by adding OkHttp's (that is library Retrofit uses for making underlying http calls) request interceptor. You can see solution or adding custom headers here.

    0 讨论(0)
  • 2020-12-30 01:07

    why not using the cookieJar option?

    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-30 01:27

    to add cookie header to okhttp request headers , add this in Interceptor:

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

    Ref:https://github.com/square/okhttp/wiki/Interceptors as mentioned by @Alexander Mironov

    Full Example code here: Hope it helps you

    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;
        }
     }    
    
    0 讨论(0)
  • 2020-12-30 01:30

    API web service example add Header

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

    when you login to system save cookies to your local on Response like

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

    and in every service you need to be autorised send your cookies , get from sharepreference and send it with your web service

      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);
    
    0 讨论(0)
提交回复
热议问题