2014-01-20 7 views
14

Ich muss wissen, wie man einen Berechtigungscookie-Header in Retrofit hinzufügt. Ich habe Ratschläge wie die Verwendung von Abfragebefehlen usw. gesehen. Unten ist, was ich versuche, aber ist das korrekt? Zuallererst brauchte ich schon einen RequestAdatper, um beim ersten Mal die Sitzungs-ID zu erhalten. Dies kann nur vom Ersteller des Anforderungsadapters festgelegt werden. Aber ich musste eine Anfrage stellen, nur um die Session-ID an erster Stelle zu bekommen. Brauche ich zwei Restadapter, um die SessionId zu erhalten, und eine weitere, nachdem ich sie erhalten habe. Was ich wirklich brauche, ist eine Methode auf dem Adapter, um das Cookie zu setzen, nachdem ich es bekommen habe, aber es scheint nicht so eine Methode zu sein. Das wird peinlich. Wie setze ich Autorisierungscookies im Retrofit? Ich sehe das nicht in FAQ oder Tutorials.RETROFIT & AUTH COOKIE

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 ??? 
+1

könnte dies für meine Anwendung nicht benötigen. aber es ist eine großartige Frage, also bitte jemand antworten. – user3186731

+0

Was haben Sie am Ende gemacht, weil der Code in der Antwort nur verwirrend ist ... und versuchen, ihn in die Seite einzufügen, auf der ich meine Anfragen anrufe. – Lion789

Antwort

26

einen Verweis auf die Abfangjäger halten und es als Singleton behandeln, wie Sie RestAdapter selbst sein würde.

Rufen Sie jetzt nach Ihrem Authentifizierungsanruf einfach setSessionId an. Alle nachfolgenden Anfragen enthalten den Header.

+0

Versuchen herauszufinden, wie man setSessionId von außerhalb der Klasse aufrufen ... ApiHeaders.setSessionId ist keine Methode ... – Lion789

+0

@ Lion789 Sie benötigen eine statische setSessionId. – wendigo

+0

@Jake Wharton: Wie bekommen wir die SessionId von der Antwort? – Chetna

12

Sie können die Cookies erhalten wie diese

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

Damit wird die CookieHandler einstellen

MyCookieManager myCookieManager = new MyCookieManager(); 
     CookieHandler.setDefault(myCookieManager); 

und es dann so in Ihrer Anfrage verwenden Interceptor

String sessionId = preference.getSessionId(); 
        if (sessionId != null) 
         requestFacade.addHeader(Cookie, sessionId); 
+0

Arbeitete gut! Danke @Chetna! –

7

Schritt 1. Parsen Sie Response-Header. Rufen Sie diese Methode in Ihrem Callback in success Methode überschrieben.

/** 
    * 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; 
    } 

Schritt 2. Schreiben Sie einige statische Klasse oder Singleton Cookies zu halten und Ihre RequestInterceptor Instanz. Innerhalb von RequestInterceptor überschreiben Sie die Abfangmethode, um Ihre Cookies zu Header hinzuzufügen.

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

Einfache Lösung mit lib. kompilieren com.squareup.okhttp3:okhttp-urlconnection:3.2.0.

JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault()); OkHttpClient.Builder().cookieJar(jncj).build();

4

Nach @ sbtgE Antwort, aber mit einigen Korrekturen. CookieHandler.getDefault() kann null sein, daher verwende ich CookieManager.

App build.gradle:

dependencies { 
    ... 
    compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1' 
} 

Einrichten 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); 
+0

Wie löschen Sie den Cookie, wenn eine Verbindung getrennt wird? –