web-dev-qa-db-fra.com

Gestion automatique des cookies avec OkHttp 3

J'utilise okhttp 3.0.1. 

Chaque fois que je reçois un exemple de traitement des cookies avec okhttp2 

OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);

Est-ce que quelqu'un peut me guider comment utiliser dans la version 3. La méthode setCookieHandler n'est pas présente dans la version 3.

27
user2672763

en ce moment je joue avec. try PersistentCookieStore , ajoute des dépendances de niveaux pour JavaNetCookieJar:

compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0-RC1"

et init

    // init cookie manager
    CookieHandler cookieHandler = new CookieManager(
            new PersistentCookieStore(ctx), CookiePolicy.ACCEPT_ALL);
    // init okhttp 3 logger
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    // init OkHttpClient
    OkHttpClient httpClient = new OkHttpClient.Builder()
            .cookieJar(new JavaNetCookieJar(cookieHandler))
            .addInterceptor(logging)
            .build();

`

29
1f7

Si vous voulez utiliser le nouveau OkHttp 3 CookieJar et vous débarrasser de la dépendance okhttp-urlconnection, vous pouvez utiliser ceci PersistentCookieJar .

Il vous suffit de créer une instance de PersistentCookieJar, puis de la transmettre au générateur OkHttp:

CookieJar cookieJar =
                    new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .cookieJar(cookieJar)
                    .build();
49
franmontiel

Ici, vous avez une approche simple pour créer votre propre CookieJar. Il peut être étendu à votre guise. Ce que j'ai fait est d'implémenter un CookieJar et de construire OkHttpClient à l'aide de OkHttpClient.Builder avec ceci, ce CookieJar.

public class MyCookieJar implements CookieJar {

    private List<Cookie> cookies;

    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        this.cookies =  cookies;
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        if (cookies != null)
            return cookies;
        return new ArrayList<Cookie>();

    } 
}

Voici comment vous pouvez créer le OkHttpClient

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cookieJar(new MyCookieJar());
OkHttpClient client = builder.build();
14
gncabrera

Voici l'implémentation de CookieJar pour OkHttp3. Si vous avez plusieurs instances de OkHttp3 (en général, vous ne devriez avoir qu'une instance et l'utiliser en tant que singletone), vous devez définir la même instance de cookiejar sur tous les clients http afin qu'ils puissent partager des cookies !!! Cette implémentation ne consiste pas en des cookies persistants (ils seront tous ignorés au redémarrage de l'application), mais il devrait être facile d'implémenter la persistance SharedPreferences au lieu d'une liste de cookies en mémoire (cookieStore).

    CookieJar cookieJar = new CookieJar() {
        private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            cookieStore.put(url.Host(), cookies);
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            List<Cookie> cookies = cookieStore.get(url.Host());
            return cookies != null ? cookies : new ArrayList<Cookie>();
        }
    };
    OkHttpClient httpClient = new OkHttpClient.Builder()
            .cookieJar(cookieJar)
            .build();
11
xyman

Ajout de compile "com.squareup.okhttp3:okhttp-urlconnection:3.8.1" à votre build.gradle.

Et puis en ajoutant 

 CookieManager cookieManager = new CookieManager();
 cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

 OkHttpClient defaultHttpClient = new OkHttpClient.Builder()
                                 .cookieJar(new JavaNetCookieJar(cookieManager))
                                 .build()

m'a aidé sans ajouter de dépendance vis-à-vis de tiers, à l'exception de celle de OkHttp.

7
Shubham

j'ai utilisé franmontiel PeristentCookieJar library pour okhttp3 et retrofit.2. L'avantage de cette approche est que vous n'avez pas besoin de manipuler votre requête okhttp. Il suffit de définir des cookies ou une session lors de la création de la modification

 allprojects {
     repositories {
         jcenter()
         maven { url "https://jitpack.io" }
     }
 }
    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
public static Retrofit getClient(Context context) {

            ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .cookieJar(cookieJar)
                    .build();
            if (retrofit==null) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(okHttpClient)
                        .build();
            }
            return retrofit;
        }
4
iman kazemayni

solution minimale qui conserve le cookie après la première utilisation

public class SharedPrefCookieJar implements CookieJar {

    Map<String, Cookie> cookieMap = new HashMap();
    private Context mContext;
    private SharedPrefsManager mSharedPrefsManager;

    @Inject
    public SharedPrefCookieJar(Context context, SharedPrefsManager sharedPrefsManager) {
        mContext = context;
        mSharedPrefsManager = sharedPrefsManager;
        cookieMap = sharedPrefsManager.getCookieMap(context);
        if (cookieMap == null) {
            cookieMap = new HashMap<>();
        }
    }

    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {

        for (Cookie cookie : cookies) {
            cookieMap.put(cookie.name(), cookie);
        }
        mSharedPrefsManager.setCookieMap(mContext, cookieMap);
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        List<Cookie> validCookies = new ArrayList<>();
        for (Map.Entry<String, Cookie> entry : cookieMap.entrySet()) {
            Cookie cookie = entry.getValue();
            if (cookie.expiresAt() < System.currentTimeMillis()) {

            } else {
                validCookies.add(cookie);
            }
        }
        return validCookies;
    }

}

avec poignard

@Module
public class ApiModule {


    @Provides
    @Singleton
    InstagramService provideInstagramService(OkHttpClient client)
    {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(InstagramService.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        InstagramService instagramService = retrofit.create(InstagramService.class);
        return instagramService;
    }


    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(SharedPrefCookieJar sharedPrefCookieJar){
        OkHttpClient client;
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if(BuildConfig.DEBUG)
        {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(new InstagramHeaderInterceptor())
                .addNetworkInterceptor(new LoggingInterceptor());

        }
        client = builder.cookieJar(sharedPrefCookieJar).build();
        return client;
    }
}
2
Vihaan Verma

J'ai utilisé la solution de @ gncabrera, mais j'ai également créé une classe d'assistance pour faciliter l'initialisation et faciliter le partage d'un CookieJar dans l'application.

public class OkHttpClientCreator {

    private static CookieJar mCookieJar;

    public static OkHttpClient.Builder getNewHttpClientBuilder(boolean isDebug, boolean useCookies) {
        if (mCookieJar == null && useCookies) {
            mCookieJar = new BasicCookieJar();
        }
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (useCookies) {
            builder.cookieJar(mCookieJar);
        }
        if (isDebug) {
            builder.addInterceptor(new LoggingInterceptor());
        }
        return builder;
    }

    public static OkHttpClient getNewHttpClient(boolean isDebug, boolean useCookies) {
       return getNewHttpClientBuilder(isDebug, useCookies).build();
    }

}

L'intercepteur de journalisation est utilisé en mode débogage pour imprimer les informations de la demande et l'instance de cookie est partagée. de sorte que, si les demandes doivent utiliser un gestionnaire de cookies commun, elles le peuvent. Ces cookies ne persisteront pas après le lancement d'applications, mais ce n'est pas une exigence pour mon application, car nous utilisons des sessions basées sur des jetons et le seul besoin de cookies est le court délai entre la connexion et la génération du jeton.

Remarque: BasicCookieJar est exactement la même implémentation que MyCookieJar de gncabrera

0
Matt Wolfe