iOS Cookie 基礎學習

iOS Cookie 概述

Cookie 提供服務器存儲相關數據到客戶端的一種解決方案, 服務器通過Response中的Http-Header的Set-Cookie來將對應的Cookie持久化到本地的問題見, 當APP下次請求該域名的時候, 會將之前緩存的Cookies信息, 一起發(fā)送給服務端, 服務端可以根據Cookie信息來做下一步處理. 可以將Cookie當做服務器分辨某個終端設備的憑證, 一般iOS中可以用來判斷該設備是否可以自動登錄, 是否有登錄態(tài).

我們碰到的Cookie可以分成以下兩類:

  • Session Cookie -- 會話Cookie是臨時Cookie, 在一次會話中有效, 當APP退出以后,該Cookie會自動失效, 被系統(tǒng)刪除.
  • 持久化Cookie -- 持久化Cookie會將Cookie存儲在APP的沙盒中,在APP退出以后,沙盒中的Cookie依然存在, 不會被刪除.

iOS系統(tǒng)中的URL Loading SystemWebKit.framework

我們知道, 在iOS中每個單獨app都一個一個獨立的數據區(qū)域, 不同的app數據區(qū)域互相不會影響.

Apple官方文檔中有以下一段:

The URL loading system automatically sends any stored cookies appropriate for an NSURLRequest object unless the request specifies not to send cookies. Likewise, cookies returned in an NSURLResponse object are accepted in accordance with the current cookie acceptance policy.

我們知道iOS中有URL Loading System, 不論我們使用的是UIWebView, 還是系統(tǒng)原生的NSURLSession或者第三方庫AFNetworking, 他們都是在這個URL Loading System之上的, 因此我們可以通過NSURLProtocol去自定義我們的網絡操作. 而上面一段文字,我們理解一下, URL Loading System會幫我們做下面兩個事情:

    1. NSURLRequest在請求發(fā)送的時候, 會自動帶上已經存儲在Cookie Storage中的cookies, 除非我們設置了NSURLRequestHTTPShouldHandleCookies屬性為不處理Cookie.
    1. NSURLResponse會根據當前APP中的NSHTTPCookieStoragecookieAcceptPolicy, 選擇是否將響應頭中的Cookie存儲在Cookie Storage中.

在iOS8以后, 蘋果又推出了WKWebView, 它是在WebKit.framework中的一套新的體系, 它不依賴URL Loading System, 因此需要區(qū)分一下不同網絡基礎體系對Cookie產生的影響:

  • NSURLSession/NSURLRequest/NSURLConnection -- 在一個app內, 共享Shared Cookie Storage(底層會走URL Loading System).
  • UIWebView -- 在一個app內, 每個UIWebView實例會繼承app中的 ``Shared Cookie Storage. (實際也可以規(guī)為第一條, 因為我們使用UIWebView時, 底層會創(chuàng)建NSURLRequest, 會走URL Loading System`)
  • WKWebview -- 每個WKWebView的實例對象都有一個與它自己關聯(lián)的 cookie storage!!!, 我們可以參考WKHTTPCookieStore.(與APP 的Shared Cookie Storage互相獨立!!!!)
  • 特殊情況: App group -- 通過sharedCookieStorageForGroupContainerIdentifier用這個方法可以獲取一個 app group 相關的cookies存儲區(qū). 方便我們用同一個證書發(fā)布的app共享CookieStorage

NSURLCache和NSHTTPCookieStroage無法操作(WKWebView)WebCore進程的緩存和Cookie。WKWebView實例不會把Cookie存入到App標準的的Cookie容器(NSHTTPCookieStorage)中,因為 NSURLSession/NSURLConnection等網絡請求使用NSHTTPCookieStorage進行訪問Cookie,所以不能訪問WKWebView的Cookie,現象就是WKWebView存了Cookie,其他的網絡類如NSURLSession/NSURLConnection卻看不到。

iOS中的Cookie相關的類

iOS 中使用了NSHTTPCookie, NSHTTPCookieStorage兩個類來處理Cookie相關的內容.

1. NSHTTPCookie

每一個被存儲的Cookie都可以用 NSHTTPCookie的實例來表示.Cookie中有以下重要的屬性:

  • NSHTTPCookieValue
  • NSHTTPCookieName
  • NSHTTPCookiePath
  • NSHTTPCookieDomain
  • NSHTTPCookieVersion
  • NSHTTPCookieExpires
  • NSHTTPCookieDiscard -- session-Only

我們可以用以下方式創(chuàng)建Cookie, 或者用其他的方式, 請參考官方文檔:

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];

[cookieProperties setObject:@"username" forKey:NSHTTPCookieName]; // Cookie 名稱
[cookieProperties setObject:@"my ios cookie" forKey:NSHTTPCookieValue]; // Cookie 值
[cookieProperties setObject:@".webank.com" forKey:NSHTTPCookieDomain]; // Cookie domain
[cookieProperties setObject:@".webank.com" forKey:NSHTTPCookieOriginURL]; // Origin URL
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath]; // Cookie Path 路徑使用
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion]; // Cookie 的版本號, 目前只有 0 . 1 兩個版本
[cookieProperties setObject:[NSDate dateWithTimeIntervalSinceNow:5] forKey:NSHTTPCookieExpires];//設置失效時間 這里設置的是5s

// String value must be either "TRUE" or "FALSE". This cookie attribute is optional. The default is "FALSE", unless this cookie is version 1 or greater and a value for NSHTTPCookieMaximumAge is not specified, in which case it is assumed to be "TRUE".
[cookieProperties setObject:@"0" forKey:NSHTTPCookieDiscard]; //設置sessionOnly, 表示這個 Cookie 是否只支持 一次session, 如果session結束, 那么cookie 失效

NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];

// **手動** 將數據請求存儲到Cookie Storage中
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
2. NSHTTPCookieStorage

它是一個單例設計, 用來管理Cookie存儲的單例. NSHTTPCookieStorage單例中的cookieAcceptPolicy屬性也能夠修改系統(tǒng)對Cookie的處理策略, 有以下幾種模式:

  • NSHTTPCookieAcceptPolicyAlways --- Accept all cookies.
  • NSHTTPCookieAcceptPolicyNever --- Reject all cookies.
  • NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain --- Accept cookies only from the main document domain.

除了系統(tǒng)的Cookie Storage自動處理Cookie以外, 我們也可以手動通過NSHTTPCookieStoragesetCookie,deleteCookie等方法來增刪改查Cookie Storage中的內容.

實際使用中發(fā)現, iOS的Cookie Storage存在者一些問題, React Native持久化sessions #9中就提到, 系統(tǒng)自動幫我們處理Cookie是不靠譜的cookie存儲, 因此在實際開發(fā)中我們盡量自己主動去處理Cookie(在NSURLRequest中手動寫入Cookie, 在收到NSHTTPResponse響應時, 手動持久化收到的Cookie).

也可以參考作者的另外一篇文章, 里面簡述了Cookie Storage Policy可能導致的bug -- iOS APP中后臺無法種植Cookie?

iOS 使用Cookie中注意問題

  • 在請求時,NSURLSession 和 NSURLConnection 會自動幫我們管理 cookie 的,但并不完善。AFNetworking 默認設置了 NSURLRequest 的 HTTPShouldHandleCookies 屬性為 YES。
  • 如果服務器設置Cookie的失效時expiresDate, 并且sessionOnlyFalse, Cookie就是持久化Cookie,會被持久化到沙盒中, App在下次啟動時, 會自動將沙盒中的Cookie加載到內存中.如果sessionOnly被設置成TRUE或者, expiresDate為空, 則不會被持久化到沙盒.
  • 不要簡單的依賴 NSHTTPCookieStoragesetCookie: 方法來做 cookie 的存儲,因為在執(zhí)行 setCookie: 時, cookie 并不是馬上就更新.NSHTTPCookieStorage state not saved on app exit. Any definitive knowledge/documentation out there?
  • cookie的httpOnly屬性是用來設置cookie是否能通過 js 去訪問。默認情況下,cookie不會帶httpOnly選項(即為空),所以默認情況下,客戶端是可以通過 js 代碼去訪問(包括讀取、修改、刪除等)這個cookie的。當cookie帶httpOnly 選項時,客戶端則無法通過js代碼去訪問(包括讀取、修改、刪除等)這個cookie.
  • 當cookie的 name/domain/path 這3個字段都相同的時候會被覆蓋.
  • 關于Domain的說明: 1. 如果顯式設置了 domain,則設置成什么,瀏覽器就存成什么;但如果沒有顯式設置,則瀏覽器會自動取 url 的 host 作為 domain 值. 2. 前面帶點‘.’和不帶點‘.’有啥區(qū)別: 帶點:任何subdomain都可以訪問,包括父domain, 不帶點:只有完全一樣的域名才能訪問,subdomain 不能.

參考文件

聊一聊 cookie
關于ios的Cookie那些事
How can I retrieve a file using WKWebView?
React Native持久化sessions #9
如何處理 iOS 原生網絡請求中的 cookie ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 嘿,親愛的老爸,轉眼你已離開三年,在這三年一千零九十五天會經常想起你,想起小時候的事,還記得嗎?我六歲時跟著姥姥一...
    靈熙媽媽閱讀 225評論 0 0
  • 年輕并不意味著多好,代表缺很多經驗,從社會摸爬滾打,經歷社會的殘酷,讓我無力感。唯有努力,前進腳踏實地,讓你觸不到...
    雅nmmm閱讀 192評論 2 0
  • 六 王家的鐵柵欄沒圍成,塘坊牛二的右眼皮讓王家老六一叉子給掀掉了的消息倒很快在村里傳來,一時間村人議論紛紛,說王三...
    女蠟筆木來閱讀 187評論 0 0

友情鏈接更多精彩內容