Object-C网络通信重定向302跳转Cookie丢失及请求头丢失

项目需求

公司后端API调用,经历多次302重定向,初始请求需在请求头中携带Referer,调用成功后,可进行数据下载。

实际问题

使用NSURLSession进行网络下载请求,跳转两次后cookie丢失及请求头中Referer消失,导致请求失败返回认证失败网页。

解决思路

拦截跳转请求,获取下次跳转的URL,强制添加消失的cookie及请求头的Referer,再进行跳转。

实现方法

  • 项目文档中注册代理类(我的项目为DownloadManager,请自行替换)
@interface DownloadManager()<NSCopying, NSURLSessionDelegate>
  • 继承代理方法
- (void)URLSession:(NSURLSession *)session  task:(NSURLSessionTask *)task 
                                  willPerformHTTPRedirection:(NSHTTPURLResponse *)response 
                                                            newRequest:(NSURLRequest *)request 
                                                 completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {
    //此函数为不进行任何操作直接用返回的request进行下一步跳转, 
    //若使用completionHandler(nil),则不会进行跳转
    completionHandler(request);
    //返回的task具有唯一性,可用来识别是哪个发送的请求:task.taskIdentifier
    //返回的response中可以获取到服务器返回的Set-Cookie
    //返回的request中可以获取到即将跳转的链接地址
}
  • 实际代码
    以下为项目需要进行的操作,实际可以根据自己需求进行更改,定义了一个SessionModel来存储对应的task.taskIdentifier及相应的Referer等信息,我实际遇到的问题为跳转请求的cookie中LID的value丢失,所以代码内进行了LID的赋值
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
                                 willPerformHTTPRedirection:(NSHTTPURLResponse *)response 
                                                           newRequest:(NSURLRequest *)request 
                                               completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {
  
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for (NSHTTPCookie *cookie in [cookieJar cookies]) {
        NSLog(@"cookie%@", cookie);
        //手动设置LID (实际需求可以和后端开发协商
        if([cookie.name isEqualToString:@"LID"]) {
            NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];  // 创建cookie属性字典
            [cookieProperties setObject:cookie.name forKey:NSHTTPCookieName]; // 手动设置cookie的name
            [cookieProperties setObject:@"LID" forKey:NSHTTPCookieValue];//手动设置cookie的value
            [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
            [cookieProperties setObject:@"HOST" forKey:NSHTTPCookieDomain];//设置cookie的host地址
            NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];//保存cookie
        }
    }

    //用返回的request.URL初始化请求,因为公司下载服务不稳定,故设置超时时间为100s
    //NSURLRequestReloadRevalidatingCacheData:验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据
    NSMutableURLRequest *nextRequest = [NSMutableURLRequest requestWithURL:request.URL 
                                                                                                                    cachePolicy:NSURLRequestReloadRevalidatingCacheData 
                                                                                                              timeoutInterval:100];
    //getSessionModel:为自定义方法,并设置Referer
    SessionModel *sessionModel = [self getSessionModel:task.taskIdentifier];
    [nextRequest setValue:sessionModel.refer forHTTPHeaderField:@"Referer"];
    //发送下个请求
    completionHandler(nextRequest);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • http://www.91ri.org/tag/fuzz-bug 通常情况下,有三种方法被广泛用来防御CSRF攻击...
    jdyzm阅读 9,693评论 0 5
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,773评论 25 709
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,668评论 19 139
  • 本篇文章篇幅比较长,先来个思维导图预览一下。 一、概述 1.计算机网络体系结构分层 2.TCP/IP 通信传输流 ...
    涤生_Woo阅读 55,499评论 24 557
  • 夏夜静谧我伸手触摸月光却让月光抚遍了我的手如果我在黑夜中睁大眼睛能不能投出我脑海中的光影回转时间仿佛忘了一万个夏天...
    房前屋后的房前阅读 1,131评论 0 0