Je dois ajouter des cookies avec Retrofit 2.0. Si je comprends bien, les cookies - les mêmes que les en-têtes. ces cookies doivent être ajoutés:
private HashMap<String, String> cookies = new HashMap();
cookies.put("sessionid", "sessionId");
cookies.put("token", "token");
celui-ci fonctionne avec Jsoup lib:
String json = Jsoup.connect(apiURL + "/link")
.cookies(cookies)
.ignoreHttpErrors(true)
.ignoreContentType(true)
.execute()
.body();
voici mon code avec demande de modification:
@GET("link")
Call<CbGet> getData(@Header("sessionid") String sessionId, @Header("token") String token);
mais cela ne fonctionne pas .... je reçois le code d'erreur 403, il n'y a donc pas de cookies dans la requête ...
une idée?
Tout d'abord: le cookie n'est pas la même chose qu'un en-tête. Cookie est un en-tête HTTP spécial nommé Cookie suivi de la liste des paires de clés et de valeurs (séparées par ";"). Quelque chose comme:
Cookie: sessionid=sessionid; token=token
Puisque vous ne pouvez pas définir plusieurs en-têtes de cookie dans la même demande vous ne pouvez pas utiliser deux annotations @Header pour des valeurs distinctes (ID de session _ et jeton dans votre échantillon). Je peux penser à une solution de contournement très hacky:
@GET("link")
Call<CbGet> getData(@Header("Cookie") String sessionIdAndToken);
Vous modifiez votre méthode pour envoyer sessionId et le jeton dans une chaîne. Donc, dans ce cas, vous devez générer manuellement une chaîne de cookie au préalable. Dans votre cas, l'objet sessionIdAndToken String devrait être égal à "sessionid = here_goes_sessionid} _; token = here_goes_token"
La solution appropriée consiste à définir des cookies en ajoutant les propriétés de OkHttp (c'est-à-dire que Library Retrofit utilise pour passer des appels http sous-jacents) request interceptor . Vous pouvez voir la solution ou ajouter des en-têtes personnalisés ici .
Exemple de service Web API: ajout d'en-tête
@FormUrlEncoded
@POST("getDriverRoutes")
Call<Guzergah> getGuzergah(@Header("Cookie") String userCookie, @Field("driver_id") int driver_id);
lorsque vous vous connectez au système, sauvegardez les cookies dans votre section locale sur Response, comme
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();
et dans chaque service, vous devez être autorisé à envoyer vos cookies, accédez à sharepreference et envoyez-le avec votre service Web.
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);
pourquoi ne pas utiliser l'option 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();
}
}