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

项目需求

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

实际问题

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

解决思路

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

实现方法

  • 项目文档中注册代理类(我的项目为DownloadManager,请自行替换)
@interface DownloadManager()
  • 继承代理方法
- (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);
}

你可能感兴趣的:(Object-C网络通信重定向302跳转Cookie丢失及请求头丢失)