美文网首页
iOS AFN 3.x Cookie的管理(最新)

iOS AFN 3.x Cookie的管理(最新)

作者: 阿木摄影 | 来源:发表于2019-05-05 12:15 被阅读0次

    文章首次整理自 个人博客->iOS AFN 3.x Cookie的管理(最新)

    问题提出

    最近遇到的这个问题,让我想到了3年前遇到的问题,这个就是Cookie的管理。接下来,我们就一步一步来看看Cookie的管理;经过半天各种尝试,iOS这边,杀掉APP,重新运行,Cookie就丢了,是什么原因呢,可以先自己猜猜看;

    2年前的插曲,容我回忆一下。。。

    2年前的尝试

    2年前,也就是17年的大概这个时候,我在一家英语在线教育公司工作,那时候,还不知道,也就是大概2个月后,公司因为模式、资金等问题解散,不过这都是后话,想看的朋友可以点击这个文章写在创业公司的那一年

    那时候,我才工作没多久,不晓得 tokenCookie 对后台有什么不一样,后台说用什么就用什么,结果,在开发中,我们用AFN 2.x,服务端的同学说自己把Cookie的有效期设置了一天,但是实际上,我们测试,很快就过期了,而且,我们通过手动设置登录返回的Cookie给服务端,结果还是很快就过期了,并且,服务端收到的Cookie跟我们给的并不一样,我们做了很多实验,测试,最后,决定切换Token,由后台生成一个Token登录返回给我们,我们存储,然后在访问接口是,给Http的头部带过去,这个事情就算完结了;

    出来混总是要还的

    image

    然而,当时,没有实际解决的问题,现在又碰到了;

    公司在做一个大平台的项目,服务端为了便于Web跟APP统一管理,登录接口都是一样的,并且跟其他API的主域名还不一样,而且,用了Cookie的校验,登录校验流程看起来就是下面这个样子的:

    image

    什么是Cookie

    Cookie的分类

    Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。

    内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie。

    简单地说,cookie就是浏览器储存在用户电脑上的一小段文本文件。cookie 是纯文本格式,不包含任何可执行的代码。

    因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。

    Http通过发送一个称为 Set-Cookie 的 HTTP 请求头来创建一个 cookie,Set-Cookie 是请求头一个字符串,大概的格式就是下面这个样子:

     Set-Cookie = "SESSION=OTMyZjViNGItNDk3OS00Y2NjLWI2MTEtODY4MmM1MGNhZTZk; Path=/",
    

    AFN Cookie的存取

    印象里,Cookie一般都是浏览器自己管理,客户端很少用,但是,既然服务端决定用了,并且Android的小伙伴都弄好了,就是我这边得找找办法;

    所幸,项目中的网络请求都是单独封装的,只需要修改底层配置manger的方法就行,也不难;搜了一下,以下是尝试的办法;

    尝试方法一

    通过创建请求序列化配置的实例设置,无效

    //            AFHTTPRequestSerializer *requestSerialization = [AFHTTPRequestSerializer serializer];
    //            requestSerialization.timeoutInterval = 15;
    //            // 设置自动管理Cookies
    //            requestSerialization.HTTPShouldHandleCookies = YES;
    //            [requestSerialization setValue:[kUserDefault objectForKey:@"Cookie"] forHTTPHeaderField:@"Cookie"];
    
    

    更详细的代码配置如下,以 GET 方法为例:

                 NSString *URL = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                AFHTTPSessionManager *manger        = [AFHTTPSessionManager manager];
    //            AFSecurityPolicy *policy            = [[AFSecurityPolicy alloc] init];
    //            [policy setAllowInvalidCertificates:YES];
    //            [manger setSecurityPolicy:[LXNetworkItem customSecurityPolicy]];
                manger.requestSerializer            = [AFJSONRequestSerializer serializer];
                manger.responseSerializer           = [AFJSONResponseSerializer serializer];
                manger.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];
                //创建请求序列化配置,这种是无效的
    //            AFHTTPRequestSerializer *requestSerialization = [AFHTTPRequestSerializer serializer];
    //            requestSerialization.timeoutInterval = 15;
    //            // 设置自动管理Cookies
    //            requestSerialization.HTTPShouldHandleCookies = YES;
    //            [requestSerialization setValue:[kUserDefault objectForKey:@"Cookie"] forHTTPHeaderField:@"Cookie"];
               
                [manger GET:URL parameters:self.params progress:^(NSProgress * _Nonnull downloadProgress) {
                    //进度
                    
                } success:^(NSURLSessionDataTask *task, id responseObject) {
    
                } failure:^(NSURLSessionDataTask *task, NSError *error) {
                
                }];
                
            }
    

    尝试方法二

    是不是这个属性设置错了:HTTPShouldHandleCookies

    这个属性,默认是YES,也就是自动管理Cookie的生命周期,设置为NO,运行,没用,当杀掉APP后,再次打开还是失效;

    上面这个的尝试,是这个文章误导我了

    解决办法

    搞了半天,头也比较大,出去透透风。。。

    仔细想想,上面的设置其实是没用的,为什么呢?

    因为,你单独创建了一个请求序列化实例,而这个实例并不是manger的属性,manger其实内部也有一个requestSerializer,这个才是真正的请求序列化配置,当然我也是尝试敲出来的,这么一修改,完美解决;

    当APP杀掉后,再次打开,接口有效;

                manger.requestSerializer.HTTPShouldHandleCookies = NO;
                manger.requestSerializer.timeoutInterval = 15;
                [manger.requestSerializer setValue:[kUserDefault objectForKey:@"Cookie"] forHTTPHeaderField:@"Cookie"];
    

    Cookie的持久化

    Cookie要保存在客户端,作为服务端校验客户端的一种身份验证,因此需要持久化,否则,当APP杀掉后,HTTP 就短了,Cookie就掉了,就会发生我遇到的问题

      NSHTTPURLResponse* response = (NSHTTPURLResponse* )task.response;
                NSDictionary *allHeaderFieldsDic = response.allHeaderFields;
                NSString *setCookie = allHeaderFieldsDic[@"Set-Cookie"];
                if (setCookie != nil) {
                    NSString *cookie = [[setCookie componentsSeparatedByString:@";"] objectAtIndex:0];
                    NSLog(@"登录之后存的cookie : %@", cookie); // 这里可对cookie进行存储
                    [kUserDefault setObject:cookie forKey:@"Cookie"];
                }
    

    Cookie的清除

    当用户退出登录后,清除本地存储的Cookie,或者当Cookie失效后,清除本地存储的Cookie,重新登录,然后再存储新的Cookie;

    以上就是本次分享,如有问题,欢迎留言探讨;

    相关文章

      网友评论

          本文标题:iOS AFN 3.x Cookie的管理(最新)

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