iOS平台下cookie的使用

作者: 花前月下 | 来源:发表于2015-07-12 15:06 被阅读31858次

    分享下最近项目用到的cookie的使用及管理

    首先,先介绍下iOS对cookie的操作的两个类:

    帖子来源于:http://blog.csdn.net/chun799/article/details/17206907

    1. NSHTTPCookie  2. NSHTTPCookieStorage

    NSHTTPCookie对象代表一个HTTP cookie。 这是一个不可改变的对象,从一个包含cookie的属性的字典初始化,这个类可以用来手动创建cookie的Properties 。

    - (NSUInteger)version

    - (NSString *)name;

    - (NSString *)value;

    - (NSString *)domain;

    - (NSString *)path;

    - (BOOL)isSessionOnly;等等属性,具体属性请自行谷歌

    可以通过手工赋值的方式创建Cookie,如

    + (id)cookieWithProperties:(NSDictionary *)properties;

    - (id)initWithProperties:(NSDictionary *)properties;

    也可以从Cookie中读取到所有属性。

    - (NSDictionary *)properties;

    使用NSHTTPCookie的类方法可以将NSHTTPCookie实例与HTTP cookie header相互转换.

    根据NSHTTPCookie实例数组生成对应的HTTP cookie header

    + (NSDictionary *)requestHeaderFieldsWithCookies:(NSArray *)cookies;

    从headerFileds中读取到Cookie相关内容,生成NSHTTPCookie实例对象数组。

    + (NSArray *)cookiesWithResponseHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)theURL;

    该方法会忽略headerFileds中与cookie无关的字段,如果headerFileds中的cookie没有指定domain,则使用theURL的domain,如果没有指定path,则使用”/”.

    除非NSURLRequest明确指定不使用cookie(HTTPShouldHandleCookies设为NO),否则URL loading system会自动为NSURLRequest发送合适的存储cookie。从NSURLResponse返回的cookie也会根据当前的cookie访问策略(cookie acceptance policy)接收到系统中。

    例如:

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];  // 创建cookie属性字典

    [cookieProperties setObject:@"username" forKey:NSHTTPCookieName]; // 手动设置cookie的属性

    [cookieProperties setObject:@"rainbird" forKey:NSHTTPCookieValue];

    [cookieProperties setObject:@"cnrainbird.com" forKey:NSHTTPCookieDomain];

    [cookieProperties setObject:@"cnrainbird.com" forKey:NSHTTPCookieOriginURL];

    [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];

    [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];  // 通过NSHTTPCookie的cookieWithProperties方法,将属性字典传入进行初始化,对象返回的是一个NSHTTPCookie对象,创建完成后进行下一步操作:

    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];  // 将手动创建返回的NSHTTPCookie对象添加到NSHTTPCookieStorage中,在iOS中使用NSHTTPCookie类封装一条cookie,通过NSHTTPCookie的方法读取到cookie的通用属性。在此声明一点:如果你的request里面明确不使用cookie,那么要讲cookie的(HTTPShouldHandleCookies设为NO),否则URL loading system会自动为NSURLRequest发送合适的存储cookie。

    下面来介绍一下NSHTTPCookieStorage对象:

    NSHTTPCookieStorage提供了管理所有NSHTTPCookie 对象的接口在OS X里,cookie是在所有程序中共享的,而在iOS中,cookie只当当前应用中有效。

    通过sharedHTTPCookieStorage方法可获取到共享的NSHTTPCookieStorage单件对象。

    + (NSHTTPCookieStorage *)sharedHTTPCookieStorage

    使用NSHTTPCookieStorage单件对象可获取到当前存储的所有cookie

    - (NSArray *)cookies

    或针对特定URL的cookie

    - (NSArray *)cookiesForURL:(NSURL *)theURL;

    还可以添加/删除Cookie

    – deleteCookie:

    – setCookie:

    – setCookies:forURL:mainDocumentURL:

    通过NSHTTPCookieStorage可读取/修改cookie接收策略,默认为NSHTTPCookieAcceptPolicyAlways.

    - (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy

    - (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)aPolicy.

    一共有三种cookie accept policy。typedef enum {

    NSHTTPCookieAcceptPolicyAlways,

    NSHTTPCookieAcceptPolicyNever,

    NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain

    }NSHTTPCookieAcceptPolicy;

    NSHTTPCookieAcceptPolicyAlways:接收所有cookie,默认策略.

    NSHTTPCookieAcceptPolicyNever: 拒绝所有cookie

    NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只接收main document domain中的cookie.

    四.相关通知

    NSHTTPCookieManagerCookiesChangedNotification

    当NSHTTPCookieStorage实例中的cookies变化时发出此通知。

    NSHTTPCookieManagerAcceptPolicyChangedNotification

    当NSHTTPCookieStorage实例的cookie acceptance policy变化时发出此通知。

    参考:

    NSHTTPCookieStorage Class Reference

    NSHTTPCookie Class Reference

    URL Loading System Programming Guide – Cookie Storage

    以上是对这两个类的综合介绍,如果有不懂,请自行百度或谷歌。

    正文

    说了这么多,就来写下我项目中用到的cookie管理

    我这个操作是保存NSHTTPCookieStorage对象里的所有cookie,当然也可以使用cookieForUrl来获取cookie进行保存,方便后续的使用。此操作是在登录的时候进行。

    下面:

     这个方法就是更新cookie。在程序每次启动的时候调用一下。用来确保每次的cookie是最新的。

    然后:

     这个方法就是移除你保存的cookie了。因为你在退出账户的时候需要重新获取新的cookie,所以,你需要在退出账户的时候清空你上次保存的cookie.   大概就是这么多操作

    staticNSString*kLocalCookieName =@"MyProjectCookie";

    staticNSString*kLocalUserData =@"MyProjectLocalUser";

    staticNSString*kServerSessionCookie =@"JSESSIONID";

    最后  

    写的不好,也没排版,请见谅。

    (写的不完善,当时也是小白,理解也不深入。如果有错误的地方或者偏差的地方给大家造成了困扰向大家道个歉。有不对的地方或者建议可以指出来,深刻的接受大家的批评与指正。)

    相关文章

      网友评论

      • 小草先生:我记得不一定需要手动保存cookie吧,AFN会在登陆时自动把cookie保存在NSHTTPCookieStorage,第二次启动APP 直接从NSHTTPCookieStorage取出cookie放在请求头 就能发送请求
        花前月下:@小草先生 有些是需要自己来管理的,看需求。 跟网页交互的时候
      • Mr_Say_Yes:算看懂了 回头实践一下 哈哈哈!!!
        花前月下:@Mr_Say_Yes 以前新手写的,也懒得改了。有错的请指正 谢谢 :smile:
      • 小草先生:你的updateCookie不是把偏好设置保存的cookie设置给cookieStorage吗,哪里有更新操作,这样做过了有效期还是会请求失败吧
        花前月下:@小草先生 重新进行认证,获取后台生成的新cookie。因为是原生+webView的方式,如果cookie失效了,那么肯定是要重新登录的,重新登录之后服务器会生成新的cookie,一旦生成新的cookie,就被保存在本地,在访问webView的时候不不需要登录了。场景是这样的。
        小草先生:@花前月下 你保存偏好设置的cookie,只是登录那时候请求到的吧 后面都没有更新操作,如果cookie有效期是15天,过期后你APP操作是提示用户重新登录 或者 直接让用户重新登录?
        花前月下:@小草先生 但是保存到偏好设置的cookie一直是保持的最新的cookie啊
      • AliceJordan:学习了谢谢~
      • 阿尔法代码狗:楼主可以加qq请问下问题么,我这有点不一样
      • 会跳舞的狮子:亲 能给个demo 来吗
        花前月下:@会跳舞的狮子 不好意思哈,最近手上两个项目,比较忙。。
      • 54iosdeveloper:能描述一下cookie具体起到作用是什么吗
        54iosdeveloper:@花前月下 好吧不过还是谢谢....
        花前月下:@54iosdeveloper 请谷歌百度,谢谢。
      • 可惜你不是我的双子座:纯原生app 会用到cookie 吗?
        花前月下:@永远不分开 原生的可能也会用到。主要是和后台的认证机制有关系。
        花前月下:@永远不分开 看实际情况
      • 指尖猿:楼主能发下原文地址吗?我记得原文地址是有一个demo 链接的
        花前月下:@指尖猿 原文地址在文章第一行。。。
      • GavinKang:楼主,我想在加载网页的时候,同步登录获得的Cookie,怎么做??求解答
      • 指尖猿:我也有这个需求 cookie 还望楼主能够帮忙 跪谢,跪谢!
        指尖猿:@花前月下 同问,楼主的绿色字 是自己定义的宏吗? 而那个宏又是什么
        指尖猿:@花前月下 楼主方便提供一个demo吗
        花前月下:@指尖猿 。。。
      • 36d170e52f5d:楼主,咨询个问题。
        1.我第一拿到cookie后保存到userDefault中,webView加载H5之前,从userDefault中取出来,然后setCookie,没有问题。
        2.当把app杀掉,再启动app,同样加载H5之前取cookie,然后setCookie,但是没有写成功,可能是什么原因呢?
        谢谢!
      • 春天的蛋蛋:我看到了。kServerSessionCookie是你静态设置的字符串。但是这句我看不太懂。。如果判断的时候。第一次不是否吗。否还会保存cookie?
      • 春天的蛋蛋:楼主。你这里的kServerSessionCookie是什么。我打不出来。看绿色感觉是关键字?
        春天的蛋蛋:@花前月下 好吧。我的代码里绿色的是关键字。现在我也不知道我的问题解决了不。偶尔会命名登陆了。却提示未登录
        花前月下:@春天的蛋蛋 就是一个常量。自定义的,绿色怎么会是关键字。。。
      • footSInRoad:看了这么多评论,楼主好耐心. :+1:
        花前月下:@rensheng :smile: 看到有评论就回复呗。也没啥。
      • 怪蜀黍罒成:我设置cookie为什么没用,楼主有空帮我看看好吗?搞的烦死了 QQ:479403486
        酉衎W:@怪蜀黍罒成 cookie 是服务器生成的,本地只负责保存或者更新
      • 注册麻烦:回答这么用心的作者必须来顶一下
        花前月下:@注册麻烦 谢谢。:smile::smile:
      • pinksnow:求demo。
      • 挂着铃铛的兔:我现在项目中在做验证码功能,后台说要获取图片验证码的时候,要传参数api_captcha , 是cookie的... 我用NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 获取不到cookie. 请问该怎么办
        挂着铃铛的兔:@花前月下 <NSHTTPCookie version:0 name:"api_captcha" value:"deleted" expiresDate:1970-01-01 00:00:01 +0000 created:2016-04-30 06:49:10 +0000 sessionOnly:FALSE domain:".api.shunliandonli.com" path:"/" isSecure:FALSE>,
        花前月下:@挂着铃铛的兔 获取不到?你打印下请求头,看看头信息里面有没有cookie
      • __西门吹雪:大哥。 如何查看我这个cookie 设置是否正确呀?
        花前月下:@__西门吹雪 登录成功就正确了。就是可以看看请求头里你设置的cookie信息
      • 花前月下:在设置特定的cookis时,需要注意以下:
        1:在NSDictionary设置字典的时候必须包含以下几项:NSHTTPCookieValue, NSHTTPCookieName, NSHTTPCookiePath, NSHTTPCookieDomain。
        2:在甚至键值对NSHTTPCookiePath时,value必须是url的Domain。

        设置的内容是url的host , @{NSHTTPCookieDomain:[url host]
      • 潸何吊:请教一下楼主 NSHTTPCookieDomain这个key是必须要带的吗。应该要设置什么内容 :grin:
      • 8ae158dda3f2:问个问题,发送请求怎么带上cookie,还是只要cookie保存本地后,发送请求都会自动带上cookie?
        8ae158dda3f2:@花前月下 嗯嗯,感谢,AFN是不是自带cookie 管理,还有是不是每次启动程序都要更新cookies
        花前月下:@_NevinZ 这个是普遍的用法。
        或者这样设置

        - ( void )connection: (NSURLConnection *)connection
        didReceiveResponse: (NSURLResponse *)response
        {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSArray *cookies;

        cookies = [ NSHTTPCookie cookiesWithResponseHeaderFields:
        [ httpResponse allHeaderFields ]];

        [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
        setCookies: cookies forURL: self.url mainDocumentURL: nil ];
        // 这个NSHTTPCookieStorage 对象就是一个cookie的管理者,你调用它的setCookie方法设置进去也是一样的。
        }

        可以参考下http://stackoverflow.com/questions/5954382/ios-is-it-possible-to-set-a-cookie-manually-using-sharedhttpcookiestorage-for-a


        - ( void )reloadWebview: (id)sender
        {
        NSArray *cookies;
        NSDictionary *cookieHeaders;
        NSMutableURLRequest *request;
        cookies = [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
        cookiesForURL: self.url ];
        if ( !cookies ) {
        /* kick off new NSURLConnection to retrieve new auth cookie */
        return;
        }
        cookieHeaders = [ NSHTTPCookie requestHeaderFieldsWithCookies: cookies ];
        request = [[ NSMutableURLRequest alloc ] initWithURL: self.url ];
        [ request setValue: [ cookieHeaders objectForKey: @"Cookie" ]
        forHTTPHeaderField: @"Cookie" ];
        [ self.webView loadRequest: request ];
        }
        花前月下:@_NevinZ

        1.例如 - 首次进入首次请求 ,
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/&quot;]];
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];

        // 接收返回值 取出cookie 保存到本地,以便于下次请求进行设置
        - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
        {
        NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
        NSDictionary *fields = [HTTPResponse allHeaderFields];
        NSString *cookie = [fields valueForKey:@"Set-Cookie"]; // It is your cookie
        }



        2. 再次请求取出cookie并设置到请求头内
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/&quot;]];
        [request addValue:cookie forHTTPHeaderField:@"Cookie"];

        http://stackoverflow.com/questions/2053568/managing-http-cookies-on-iphone
      • 乡道狗毛草:写的不错 重新排版一下
        白牛桑:哎哟,我看到了谁
        花前月下:@乡道狗毛草 谢谢。嘿嘿,写的还不是很好。只是当时用的时候自己的理解。可能还会有点偏差。 这篇文章是很早之前写的。一直没有抽出空重新整理。
      • 511bc135ce88:纯原生app 会用到cookie 吗?
        AliceJordan:有的时候会用到的,主要看你们后台的
      • 奔跑的小菜菜:NSHTTPCookieStorage保存的cookie默认是多久,我发现我的项目中的cookie一段时间后就自动清除了,因为那是个H5的页面,访问需要cookie,比如我今天登录,H5的数据是有的,可能一段时间后就获取不到内容了(登录状态),重新登录就可以解决,所以我怀疑是cookie被清除的问题,帮忙看看。
        花前月下:@奔跑的小菜菜 这个是后台定义的session会话有效期。得问后台。
        奔跑的小菜菜:多长时间
        花前月下:那就重新获取一下。 session 是有 过期时间的,也就是 会话时间
      • 22ee0fa80171:最好能结合案例介绍下😋
      • 22ee0fa80171:学习了,请教下,在webview开发中,是否可以用这个来自动登陆,是不是只需要在cookie里设置账户密码就可以了?具体没做过,希望您能讲解下
        花前月下:@CoderJohnhao :+1:
        CoderJohnhao:@花前月下 webView可以新建一个继承NSURLProtocol的工具类,并遵守NSURLConnectionDelegate,可以监听webView的网络请求,可以在NSURLConnectionDelegate的代理方法监听到网络请求返回来的数据:
        - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        NSHTTPURLResponse *httpresponse = (NSHTTPURLResponse *)response;
        if([httpresponse respondsToSelector:@selector(allHeaderFields)]);
        花前月下:@哟_Json 可以设置请求头。 首次登录成功后,将用户名密码保存在请求头里面以后请求直接带这个。webView的自动登陆我没做过。 嘿嘿。
      • 碧霄问鼎:设置一下,使用 MarkDown 来写,页面就好了。
        花前月下:@碧霄问鼎 嗯。😁
      • 司马捷:搜索 MarkDown 如何使用
        花前月下:@机器人小雪 嗯。好的。多谢提醒

      本文标题:iOS平台下cookie的使用

      本文链接:https://www.haomeiwen.com/subject/sdsuqttx.html