I need to know how to add an authorization cookie header in retrofit. I have seen advice like using request intercepter etc. Below is what I am trying, but is this correct? First of all I already needed a RequestAdatper to get the session id the first time around. This can only be set by the builder of the request adapter. But I needed to make a request just to get the session id in the first place. Do I need two rest adapters one to get the sessionId and another one after I have obtained it. What I really need is a method on adapter to set the cookie after I get it but it does not appear to be such a method. This is getting awkward. How do I set authorization cookie in retrofit? I don't see this in FAQ or tutorials.
RequestInterceptor requestInterceptor = new RequestInterceptor()
{
@Override
public void intercept(RequestFacade request) {
request.addHeader("Set-Cookie", "sessionId="+sessionIdentifier);
}
};
RestAdapter.Builder().setServer(serverURL)..setRequestIntercepter(requestIntercepter).build();
// but I don't have sessionId when this is first issued ???
Keep a reference to the interceptor and treat it as a singleton like you would be RestAdapter
itself.
public class ApiHeaders implements RequestInterceptor {
private String sessionId;
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public void clearSessionId() {
sessionId = null;
}
@Override public void intercept(RequestFacade request) {
if (sessionId != null) {
request.setHeader(...);
}
}
}
Now, simply call setSessionId
after your authentication call. All subsequent requests will include the header.
You can get the cookies like this
public class MyCookieManager extends CookieManager {
@Override
public void put(URI uri, Map<String, List<String>> stringListMap) throws IOException {
super.put(uri, stringListMap);
if (stringListMap != null && stringListMap.get("Set-Cookie") != null)
for (String string : stringListMap.get("Set-Cookie")) {
if (string.contains("JSESSIONID")) {
Preference.getInstance().setSessionId(string);
}
}
}
}
Use this to set the CookieHandler
MyCookieManager myCookieManager = new MyCookieManager();
CookieHandler.setDefault(myCookieManager);
and then use it like this in your request Interceptor
String sessionId = preference.getSessionId();
if (sessionId != null)
requestFacade.addHeader(Cookie, sessionId);
Step 1. Parse Response headers.
Call this method inside your Callback in overriden success
method.
/**
* Method extracts cookie string from headers
* @param response with headers
* @return cookie string if present or null
*/
private String getCookieString(Response response) {
for (Header header : response.getHeaders()) {
if (null!= header.getName() && header.getName().equals("Set-Cookie")) {
return header.getValue();
}
}
return null;
}
Step 2. Write some static class or singleton to keep cookies and your RequestInterceptor instance. Inside RequestInterceptor override intercept method to add your cookies to Header.
public class RestAdapter {
private static String cookies;
public static String getCookies() {
return cookies;
}
public static void setCookies(String cookies) {
RestAdapter.cookies = cookies;
}
/**
* Injects cookies to every request
*/
private static final RequestInterceptor COOKIES_REQUEST_INTERCEPTOR = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
if (null != cookies && cookies.length() > 0) {
request.addHeader("Cookie", cookies);
}
}
};
public static final RestInterface getService() {
return new RestAdapter.Builder()
.setEndpoint(Config.ENDPOINT)
.setRequestInterceptor(COOKIES_REQUEST_INTERCEPTOR)
.setConverter(new JacksonConverter())
.setLogLevel(RestAdapter.LogLevel.NONE)
.build()
.create(RestInterface.class);
}
}
According to @sbtgE's answer, but with some corrections. CookieHandler.getDefault()
may be null, so I use CookieManager.
app's build.gradle:
dependencies {
...
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
}
Setting up Retrofit:
service = new Retrofit.Builder()
.baseUrl(/* your base URL */)
.addConverterFactory(/* your favourite converter */)
.client(
new OkHttpClient.Builder()
// this line is the important one:
.cookieJar(new JavaNetCookieJar(new CookieManager()))
.build())
.build()
.create(YourInterface.class);
Simple solution using lib. compile com.squareup.okhttp3:okhttp-urlconnection:3.2.0
.
JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault());
OkHttpClient.Builder().cookieJar(jncj).build();