cookie in iOS

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


Cookie介紹

Cookie分類兩類:

  • 會話cookie
  • 持久cookie

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

cookie如何工作

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


cookie工作

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

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



    • cookie 0首部:

Cookie: session-id=002-1145265-8016838; session-id-time=1007884800
  • cookie版本1
    • Set-Cookie2首部
      這個版本 1 標準引入了Set-Cookie2首部和Cookie2首部,但它也能于版本0進行交互操作。


    • 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的實現(xiàn)是一個單例對象,管理著NSHTTPCookie對象,會話cookie的 sessionOnly方法返回YES就不可在進程間共享。

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

Cookies are not shared among applications in iOS.

  • iOS中cookie不能跨應用共享

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

NSHTTPCookieStorage可以管理cookie的接受策略,在一個app中改變cookie的接受策略將會影響其他正在運行的app的cookie接受策略。

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

Cookie接受策略:
NSHTTPCookieAcceptPolicy

typedef NS_ENUM(NSUInteger, NSHTTPCookieAcceptPolicy) {
    NSHTTPCookieAcceptPolicyAlways,//默認策略,接受所有的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類封裝了一個HTTP Cookie,并提供常見的Cookie屬性訪問接口。NSHTTPCookie可以轉換HTTP Cookie成NSHTTPCookies對象,并可以將NSHTTPCookie對象轉化為NSURLRequest對象的請求頭部分。URL loading system 會自動地給NSURLRequest對象發(fā)送存儲的cookie,除非NSURLRequest對象指定不需要傳cookie,同樣cookie在NSURLRequest中返回也按照當前的cookie接受策略接收。


Cookie使用??個??

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

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

  • 客戶端手動設置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:進行設置cookie的時候,會覆蓋name,domain,path都相同的cookie的。
至于cookie會不會持久化到cookie文件中主要看這個cookie的生命周期,和Max-Age或者Expires有關。

  • 通過HTTP Header的Set-Cookie后者Set-Cookie2設置Cookie
 //請求一個網(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進行歸檔并轉換為NSData類型
         * 注意:cookie不能直接轉換為NSData類型,否則會引起崩潰。
         * 所以先進行歸檔處理,再轉換為Data
         */
        NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
 
        //存儲歸檔后的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進行反歸檔處理
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:[userDefaults objectForKey:@"cookie"]];
 
    if (cookies) {
        //設置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 權威指南》第11章 客戶端識別與cookie機制


相關導引

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

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


喜歡就賞個贊吧~
歡迎關注我的博客??冷讀空間

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容