Добавить файлы cookie для обновления 2 запроса
Мне нужно добавить файлы cookie с модификацией 2.0. Если я правильно понимаю, файлы cookie - то же, что и заголовки. эти файлы cookie должны быть добавлены:
private HashMap<String, String> cookies = new HashMap();
cookies.put("sessionid", "sessionId");
cookies.put("token", "token");
эта работа работает с Jsoup lib:
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...
любая идея?
Ответы
Ответ 1
Прежде всего: cookie не совпадает с заголовком. Cookie - это специальный HTTP-заголовок с именем Cookie, за которым следует список пар ключей и значений (разделенных символом ";" ). Что-то вроде:
Cookie: sessionid=sessionid; token=token
Поскольку вы не можете установить несколько заголовков Cookie в одном запросе, вы не можете использовать две аннотации @Header для отдельных значений (sessionid и токен в вашем примере). Я могу думать об одном очень хакерском обходном пути:
@GET("link")
Call<CbGet> getData(@Header("Cookie") String sessionIdAndToken);
Вы меняете свой метод для отправки sessionId и токена в одну строку. Поэтому в этом случае вы должны вручную создать строку cookie заранее. В вашем случае объект sessionIdAndToken String должен быть равен "sessionid = here_goes_sessionid; token = here_goes_token"
правильное решение состоит в том, чтобы установить файлы cookie, добавив OkHttp (это библиотека, которую использует Retrofit для создания базовых вызовов http) запрос перехватчика. Вы можете увидеть решение или добавить пользовательские заголовки здесь.
Ответ 2
добавить заголовок cookie в заголовки заголовков okhttp, добавить это в Interceptor:
request= request.newBuilder().addHeader("Cookie", sessionIdAndToken).build();
Ссылка: https://github.com/square/okhttp/wiki/Interceptors, как упоминал @Alexander Миронов
Полный пример кода здесь: Надеюсь, он поможет вам
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;
}
}
Ответ 3
Пример веб-службы API добавить заголовок
@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
почему бы не использовать опцию 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();
}
}