2016-07-17 23 views
7

Muszę dodać pliki cookie z modernizacją 2.0. Jeśli rozumiem poprawnie, pliki cookie - takie same jak nagłówki. Ciasteczka to należy dodać:Dodaj pliki cookie do retrofitu 2 żądanie

private HashMap<String, String> cookies = new HashMap(); 
cookies.put("sessionid", "sessionId"); 
cookies.put("token", "token"); 

ta praca z Jsoup lib:

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

tutaj jest mój kod z prośbą modernizacji:

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

ale to nie działa. .. Otrzymuję kod błędu 403, więc nie ma plików cookie w żądaniu ...

dowolna dea?

+0

http://stackoverflow.com/questions/34881775/automatic-cookie-handling-with-okhttp-3 – USKMobility

Odpowiedz

25

Po pierwsze: plik cookie nie jest taki sam jak nagłówek. Cookie to specjalny nagłówek HTTP o nazwie Cookie, po którym następuje lista par kluczy i wartości (oddzielonych znakiem ";"). Coś jak:

Cookie: sessionid=sessionid; token=token 

Od you cannot set multiple Cookie headers in the same request nie są w stanie korzystać z dwóch @Header adnotacje na oddzielnych wartości (sessionid i żeton w próbce). Mogę myśleć o jednym bardzo hacky obejścia:

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

zmienić metodę wysyłania sessionid i token w jeden ciąg. Dlatego w tym przypadku należy ręcznie wygenerować ciąg znaków cookie. W twoim przypadku obiektu sessionIdAndToken String powinien być równy „sessionid = here_goes_sessionid; żeton = here_goes_token

prawidłowe rozwiązanie jest na ustawianie ciasteczek dodając OkHttp „s (czyli Modernizacja biblioteki używa do wykonywanie bazowych połączeń HTTP) request interceptor. Możesz zobaczyć rozwiązanie lub dodać niestandardowe nagłówki here.

+1

Działa idealnie. próbowałem z hacky way :) –

2

dodać nagłówek cookie okhttp nagłówki żądania, należy dodać to w Interceptor:

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

Ref: https://github.com/square/okhttp/wiki/Interceptors jak wspomniano

Pełna Przykładowy kod tutaj @Alexander Mironow: Mam nadzieję, że to pomaga

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

Przykładowy serwis WWW API dodaj nagłówek

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

podczas logowania do systemu oszczędzania cookies do lokalnej o odpowiedź jak

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

iw każdej usługi musisz można zezwolić wysłać cookies, otrzymasz od sharepreference i wysłać go z usługą internetową

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