cookie in iOS

項(xiàng)目中用到了本地登錄存儲(chǔ)cookie,再進(jìn)行webView請求時(shí)間帶上cookie的功能。不是很清晰邏輯,于是學(xué)習(xí)了解了下iOS中cookie的使用,做個(gè)小結(jié)。不想看介紹的朋友可跳過到最后一節(jié)直接看使用??(#example)


Cookie介紹

Cookie分類兩類:

  • 會(huì)話cookie
  • 持久cookie

會(huì)話 cookie 和持久 cookie 之間唯一的區(qū)別就是它們的過期時(shí)間。

cookie如何工作

cookie 中包含了一個(gè)由 名字 = 值 (name=value) 這樣的信息構(gòu)成的任意列表,并通過 Set-Cookie 或 Set-Cookie2 HTTP 響應(yīng)(擴(kuò) 展)首部將其貼到用戶身上去。


cookie工作

cookie組成
現(xiàn)在使用的 cookie 規(guī)范有兩個(gè)不同的版本:cookies 版本 0(有時(shí)被稱為 Netscape cookies) 和 cookies 版 本 1(RFC 2965) 。 cookies 版 本 1 是 對 cookies 版 本 0 的 擴(kuò) 展,應(yīng)用不如后者廣泛。

  • cookie版本0
    • Set-Cookie 首部
      Set-Cookie 首部有一個(gè)強(qiáng)制性的cookie名和cookie值。后面跟著可選的cookie 屬性,中間由分號分隔。



    • cookie 0首部:

Cookie: session-id=002-1145265-8016838; session-id-time=1007884800
  • cookie版本1
    • Set-Cookie2首部
      這個(gè)版本 1 標(biāo)準(zhǔn)引入了Set-Cookie2首部和Cookie2首部,但它也能于版本0進(jìn)行交互操作。


    • cookie 1首部:

Cookie: $Version="1";
ID="29046"; $Domain=".joes-hardware.com";
color="blue";
Coupon="hammer027"; $Path="/tools";
Coupon="handvac103"; $Path="/tools/cordless"

NSHTTPCookieStorage

NSHTTPCookieStorage implements a singleton object (shared instance) that manages storage of cookies. Each cookie is represented by an instance of the NSHTTPCookie class. As a rule, cookies are shared among all applications and are kept in sync across process boundaries. Session cookies (where the cookie object’s sessionOnly method returns YES) are local to a single process and are not shared.

NSHTTPCookieStorage的實(shí)現(xiàn)是一個(gè)單例對象,管理著NSHTTPCookie對象,會(huì)話cookie的 sessionOnly方法返回YES就不可在進(jìn)程間共享。

然而蘋果在這個(gè)類的API Reference中寫了一個(gè)iOS Note

Cookies are not shared among applications in iOS.

  • iOS中cookie不能跨應(yīng)用共享

  • MacOSsessionOnly不為YES是可以被共享的

NSHTTPCookieStorage可以管理cookie的接受策略,在一個(gè)app中改變cookie的接受策略將會(huì)影響其他正在運(yùn)行的app的cookie接受策略。

當(dāng)其他的app修改了cookie存儲(chǔ) 或者 cookie接受策略,NSHTTPCookieStorage將會(huì)給app發(fā)送NSHTTPCookieManagerCookiesChangedNotification或者NSHTTPCookieStorageAcceptPolicyChangedNotification通知

Cookie接受策略:
NSHTTPCookieAcceptPolicy

typedef NS_ENUM(NSUInteger, NSHTTPCookieAcceptPolicy) {
    NSHTTPCookieAcceptPolicyAlways,//默認(rèn)策略,接受所有的cookies
    NSHTTPCookieAcceptPolicyNever,//拒絕所有的cookies
    NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain//只從主文檔域名接受cookies
};

NSHTTPCookie

An NSHTTPCookie object represents an HTTP cookie. It is an immutable object, initialized from a dictionary containing the cookie attributes.

NSHTTPCookie對象中包含了HTTP 的cookie對象,從包含cookie字段的字典初始化創(chuàng)建。

The NSHTTPCookie class encapsulates a cookie, providing accessors for many of the common cookie attributes. This class also provides methods to convert HTTP cookie headers to NSHTTPCookie instances and convert an NSHTTPCookie instance to headers suitable for use with an NSURLRequest object. 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.

NSHTTPCookie類封裝了一個(gè)HTTP Cookie,并提供常見的Cookie屬性訪問接口。NSHTTPCookie可以轉(zhuǎn)換HTTP Cookie成NSHTTPCookies對象,并可以將NSHTTPCookie對象轉(zhuǎn)化為NSURLRequest對象的請求頭部分。URL loading system 會(huì)自動(dòng)地給NSURLRequest對象發(fā)送存儲(chǔ)的cookie,除非NSURLRequest對象指定不需要傳cookie,同樣cookie在NSURLRequest中返回也按照當(dāng)前的cookie接受策略接收。


Cookie使用??個(gè)??

Cookie生成的有兩個(gè)途徑,一個(gè)是訪問一個(gè)網(wǎng)頁,這個(gè)網(wǎng)頁返回的HTTP Header中有Set-Cookie指令進(jìn)行Cookie的設(shè)置,這里Cookie的本地處理其實(shí)是由WebKit進(jìn)行的;還有一種途徑就是客戶端通過代碼手動(dòng)設(shè)置Cookie。

值得注意iOS Cookie使用提到:
NSHTTPCookieStorage存在一個(gè)問題,setCookie或者deleteCookie后并不會(huì)立即進(jìn)行持久化,而是有幾秒的延遲。為了可靠性,我們會(huì)將cookie信息保存一份到User Defaults,需要用的時(shí)候load進(jìn)來。

  • 客戶端手動(dòng)設(shè)置Cookie
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"name" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"value" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"www.taobao.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
[cookieProperties setObject:@"30000" forKey:NSHTTPCookieMaximumAge];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
//刪除cookie的方法為deleteCookie:

在通過setCookie:進(jìn)行設(shè)置cookie的時(shí)候,會(huì)覆蓋name,domain,path都相同的cookie的。
至于cookie會(huì)不會(huì)持久化到cookie文件中主要看這個(gè)cookie的生命周期,和Max-Age或者Expires有關(guān)。

  • 通過HTTP Header的Set-Cookie后者Set-Cookie2設(shè)置Cookie
 //請求一個(gè)網(wǎng)址,即可分配到cookie
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer = [AFJSONResponseSerializer new];
    [manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
 
        //獲取cookie
        NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
        
        /*
         * 把cookie進(jìn)行歸檔并轉(zhuǎn)換為NSData類型
         * 注意:cookie不能直接轉(zhuǎn)換為NSData類型,否則會(huì)引起崩潰。
         * 所以先進(jìn)行歸檔處理,再轉(zhuǎn)換為Data
         */
        NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
 
        //存儲(chǔ)歸檔后的cookie
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        [userDefaults setObject: cookiesData forKey: @"cookie"];
        [self setCookie];
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 
    }];
    
    - (void)setCookie
{
    //取出保存的cookie
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
 
    //對取出的cookie進(jìn)行反歸檔處理
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:[userDefaults objectForKey:@"cookie"]];
 
    if (cookies) {
        //設(shè)置cookie
        NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        for (id cookie in cookies) {
            [cookieStorage setCookie:(NSHTTPCookie *)cookie];
        }
    }else{
        NSLog(@"無cookie");
   }  
}

參考

NSHTTPCookieStorage

Cookies and Custom Protocols

http://geeklu.com/2013/04/ios-cookie/

http://blog.it985.com/11248.html

《HTTP 權(quán)威指南》第11章 客戶端識別與cookie機(jī)制


相關(guān)導(dǎo)引

解決UIWebView和WKWebView之間的cookie共享問題:

iOS開發(fā)-打通UIWebView和WKWebView的Cookie


喜歡就賞個(gè)贊吧~
歡迎關(guān)注我的博客??冷讀空間

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容