Android 中的Cookie瞭解一下

閱讀完本文你將收穫

  • Cookie是什麼,有什麼用
  • Android 中的Cookie是如何存儲的
  • Cookie中字段的具體含義及如何解析

Cookie 是什麼

  1. 在咱們進行網絡請求時,一般使用的是Http協議,例如在瀏覽器裏輸入http:www.baidu.com請求百度網站。html

  2. HTTP/1.1 是無狀態協議,即server並不知道客戶端的狀態。如請求了A接口進行登陸,再請求B接口獲取數據時,若是不在請求接口B時手工拼接一些登陸參數,那麼server並不知道咱們此時是否登陸。在每一個接口都拼接一些參數,這未免有些麻煩,這個時候Cookie登場了。web

  3. 利用Cookie能夠在客戶端緩存一些數據,或者持久化存儲這些數據。在特定的條件下,會在網絡請求時將這些數據帶上,這樣server和客戶端的連接就有了"狀態"。例如,server能夠在登錄成功時將登錄狀態(token)記錄在客戶端的cookie中,在下次請求server時,只要知足條件,客戶端就會自動將cookie一併發送給server,這樣server就知道了客戶端的登錄狀態。數據庫

Http和WebView的Cookie

  1. 在WebView的一次Http請求中,server能夠在請求返回的Response的Header中設置Cookie,在webview接受到這些Cookie時,會根據含義將他們進行緩存或者存儲,如
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: theme=light
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
複製代碼
  1. 當進行網絡請求時,若是符合條件,webview會幫咱們在請求中帶上已經存儲的cookie,如
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123
複製代碼
  1. WebView會將這些Cookie存儲在哪裏呢?若是Cookie沒有過時,而且須要持久化存儲,WebView一般會將他們存儲在數據庫中

Android 中的Cookie

上文講了WebView中的Cookie存儲,那麼在非webview的場景,會用到Cookie嘛?答案是會的,例如:咱們在Android App中進行登陸,而後在App打開一個web,web如何知道咱們是否登陸了呢?咱們能夠藉助Cookie,在調用Http請求登錄成功將對應的登錄信息寫入到Cookie中,web讀取這些信息就知道咱們是否登陸了瀏覽器

利用CookieManager存儲和讀取Cookie

Android中的WebKit爲咱們提供了CookieManager,它是一個單例,咱們能夠利用它進行Cookie的讀取和存儲,例如緩存

/**
     * Sets a cookie for the given URL. Any existing cookie with the same host,
     * path and name will be replaced with the new cookie. The cookie being set
     * will be ignored if it is expired.
     *
     * @param url the URL for which the cookie is to be set
     * @param value the cookie as a string, using the format of the 'Set-Cookie'
     *              HTTP response header
     */
 val value = "gw_id=6404; Path=/; Max-Age=86400; HttpOnly"
 CookieManager.getInstance().setCookie(url, value)
 CookieManager.getInstance().getCookie(url)
複製代碼

域名共享Cookie

在一些場景下,若是須要不一樣的域名共享Cookie,咱們須要進行一些額外的操做,爲何呢?安全

  1. 一條Cookie包含若干屬性,其中包括它生效的域名(host)、name、path,例如上面例子中url是域名,gw_id是name, / 是path。
  2. 咱們前面提到,只有在特定的條件下,web纔會在一次請求中將cookie帶給server,這個特定的條件就是cookie的域名和當前請求的域名相等。
  3. 可是每每有一些特殊的場景,例如公司有N個域名,用戶在A域名的網站登陸了,若是再去瀏覽B域名下的網站,難道還須要再登陸一次?這個時候就須要域名共享
  4. 在Android中域名共享能夠利用上面的CookieManager,在特定的時機先讀取A域名的Cookie,而後設置給B域名,這樣B域名就能夠訪問A域名的Cookie了

解析數據庫中的Cookie

  1. 前面有提到Cookie通常是儲存在數據庫中,那麼在Android中呢?這個數據庫位於 data/data/包名/aap_webview下的Cookies文件,不一樣Android系統可能有所差別,例如華爲位於 data/data/包名/aap_webview/default下

  1. 既然是數據庫文件,天然就能夠經過數據庫進行解析,咱們能夠經過上文CookieManager的setCookie方法設置一些Cookie(注意:數據庫存在緩存,使用CookieManager進行存取後並不會當即寫入Cookies,若是想當即寫入,能夠調用CookieManager的flush()方法),而後將Cookies文件取出,並更更名稱爲Cookies.db,以後用數據庫軟件(做者用了DB Browser for Sqlite)進行讀取(注意:不一樣版本的webview生成的表的關鍵字可能不一樣)。

  1. 上面第一張圖顯示了字段的類型和默認值,第二張圖展現了一個示例,那麼這些字段都是什麼含義呢?
key 含義
creation_utc Cookie產生的utc時間
host_key 當前cookie生效的域名(domain)(設置父域名,對子域名也生效)
name 要保存的key3value要保存的value(未加密
path 路徑,如/docs/Web/,如設置的話,cookie僅對當前路徑生效
expires_utc Cookie的失效時間,單位ms
is_secure 若是爲true,只有在https是纔會傳送改cookie,http不會傳送
is_httponly 若是爲true,該cookie不該被客戶端操做(經過JavaScript的 Document.cookie API沒法訪問帶有HttpOnly 標記的Cookie),只應發送給server處理
last_access_utc 上一次訪問到該Cookie的utc時間
has_expires Cookie的期限是否有效
is_persistent 若是expires_utc不爲0,那麼這個值爲1(有兩種存儲類型的Cookie:會話性與持久性。Expires屬性缺省時,爲會話性Cookie,僅保存在客戶端內存中,並在用戶關閉瀏覽器時失效)
priority Cookie的刪除優先級,Cookie也有存儲上限的,當超出上限則須要刪除,此時會有特定的刪除策略來刪除不一樣priority的Cookie
encrypted_value 加密後的value值
samesite None(0)瀏覽器會在同站請求、跨站請求下繼續發送cookies,不區分大小寫。 Strict(2)瀏覽器將只發送相同站點請求的cookie(即當前網頁URL與請求目標URL徹底一致)。若是請求來自與當前location的URL不一樣的URL,則不包括標記爲Strict屬性的cookie。 Lax(1)在新版本瀏覽器中,爲默認選項,Same-site cookies 將會爲一些跨站子請求保留,如圖片加載或者frames的調用,但只有當用戶從外部站點導航到URL時纔會發送。
firstpartyonly first-party以及third-party是HTTP Request的一種分類,first-party指的是當前所發送的HTTP請求的URL跟瀏覽器地址欄上的URL一致;不然就是third-party。
  1. firstpartyonly 在以前截圖中並無出現,爲何呢,正如以前所說的,不一樣版本webview所生成的表的key是不同的,在部分版本中會用firstpartyonly取代samesite,相似的還有用persistent取代is_persistentbash

  2. samesite講了這麼多,到底啥意思?他的做用其實很簡單,假設咱們有一個場景,在A域名的網頁下,須要請求B域名,那麼這時候Cookie怎麼帶?會不會不安全?這個時候samesite就發揮了做用,詳見cookie

  3. 上邊還提到了utc時間,經過截圖能夠看到他大概長這樣:13260634474538121,這是個什麼標準的時間?它是從1601年1月1日開始計時,以微妙爲單位的時間。它與咱們經常使用的1970年1月1日中間相差了11644473600妙網絡

  4. 在字段的說明中咱們有提到,is_persistent 和 has_expires代表一個cookie是否有過時時間,當cookie到達expires_utc過時時間時,cookie就會失效,咱們將再也不能從we獲取到這個cookie。可是又一種特殊的場景,若是expires_utc爲0,is_persistent爲0,has_expires爲0,咱們仍能從web或者CookieManager獲取到這條Cookiesession

相關文章
相關標籤/搜索