Android 使用Okhttp/Retrofit持久化cookie的簡便方式


首先cookie是什么就不多說了,還是不知道的話推薦看看這篇文章 
Cookie/Session機制詳解 
深入解析Cookie技術

為什么要持久化cookie也不多說了,你能看到這篇文章代表你有這個需求。

cookie簡單來說就是服務器在客戶端中保存的鍵值對,比如說早期的購物車,保持登陸狀態都是使用的cookie。 
但是cookie的功能是依賴於瀏覽器的,大多數瀏覽器都有管理cookie的功能。當然,你也能通過設置禁止掉這項功能,畢竟cookie是很容易泄露用戶隱私的

上面也說了cookie功能依賴於客戶端,很明顯,在開發app的時候我們也要手動管理cookie了。

 

持久化cookie之前,我們最好了解一下cookie是怎么傳輸的,看完之后我想你就能使用很簡單的方式去保持cookie了。

1. cookie是怎么傳輸的

Cookie使用HTTPHeader傳遞數據。 
Cookie機制定義了兩種報頭:Set-Cookie報頭和Cookie報頭。

Set-Cookie報頭包含於Web服務器的響應頭(ResponseHeader)中 
Cookie報頭包含在瀏覽器客戶端請求頭(ReguestHeader)中

Cookie的運行過程如圖所示,具體分析如下 
這里寫圖片描述

2. 簡單粗暴持久化cookie的方式

方法來源於這http://tsuharesu.com/handling-cookies-with-okhttp/

看了cookie的傳輸原理之后我們就可以用一個簡單的方式持久化cookie了,那就是通過okhttp的intercept方式手動往header中寫入cookie或者獲取cookie。

/**
 * This interceptor put all the Cookies in Preferences in the Request.
 * Your implementation on how to get the Preferences MAY VARY.
 * <p>
 * Created by tsuharesu on 4/1/15.
 */
public class AddCookiesInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();
        HashSet<String> preferences = (HashSet) Preferences.getDefaultPreferences().getStringSet(Preferences.PREF_COOKIES, new HashSet<>());
        for (String cookie : preferences) {
            builder.addHeader("Cookie", cookie);
            Log.v("OkHttp", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
        }

        return chain.proceed(builder.build());
    }
}
/**
 * This Interceptor add all received Cookies to the app DefaultPreferences.
 * Your implementation on how to save the Cookies on the Preferences MAY VARY.
 * <p>
 * Created by tsuharesu on 4/1/15.
 */
public class ReceivedCookiesInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());

        if (!originalResponse.headers("Set-Cookie").isEmpty()) {
            HashSet<String> cookies = new HashSet<>();

            for (String header : originalResponse.headers("Set-Cookie")) {
              cookies.add(header);
            }

            Preferences.getDefaultPreferences().edit()
                    .putStringSet(Preferences.PREF_COOKIES, cookies)
                    .apply();
        }

        return originalResponse;
    }
}
/**
 * Somewhere you create a new OkHttpClient and use it on all your requests.
 */
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(new AddCookiesInterceptor());
okHttpClient.interceptors().add(new ReceivedCookiesInterceptor());

簡單的cookie持久化可以用這種方式,創建一個單例的client,全局都使用這個client請求接口。當然你也可以每次new一個client重新設置intercept……

還要記住的是,cookie是針對於域名存儲的。比如:www.baidu.com和image.baidu.com存儲的cookies都是不一樣的…… 
如果你的app真的需要同時訪問兩個域名的接口,並且兩個都需要持久化cookie,那么記得做判斷(比如用域名作為key存儲cookie到sharepreference中)。否則兩個域名的cookie會互相覆蓋掉……

3. 本體在這里,okhttp 3.0 cookie的管理

相關原理可以看看這篇文章 OkHttp3之Cookies管理及持久化

然后,持久化管理cookie可以直接使用這個開源庫,簡單到爆炸…… 
https://github.com/franmontiel/PersistentCookieJar

當然,你也可以使用鴻洋大神的okhttputils,該庫也提供了cookie的持久化管理工具。用起來和上面一樣方便


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM