Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add cookies to retrofit 2 request

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<String, String> cookies = new HashMap(); cookies.put("sessionid", "sessionId"); cookies.put("token", "token"); 

this one work with Jsoup lib:

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

here is my code with retrofit request:

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

but it is doesn't work... i get 403 error code so there are no cookies in the request...

any idea?

like image 370
Stan Malcolm Avatar asked Jul 17 '16 07:07

Stan Malcolm


People also ask

How do I add cookies to retrofit?

this cookies must be added: private HashMap<String, String> cookies = new HashMap(); cookies. put("sessionid", "sessionId"); cookies. put("token", "token");

How do I add retrofit library?

Go to File ⇒ New Project. When it prompts you to select the default activity, select Empty Activity and proceed. Open build. gradle in (Module :app ) and add Retrofit , Picasso , RecyclerView , Gson dependencies like this.


2 Answers

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.

like image 171
Alexander Mironov Avatar answered Sep 17 '22 12:09

Alexander Mironov


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();     } } 
like image 33
Markus Schulz Avatar answered Sep 16 '22 12:09

Markus Schulz