When I do a POST using AFNetworking, and I set
[server setParameterEncoding:AFJSONParameterEncoding];
Cookies do not get sent, if I do a GET then cookies do get sent.
Any ideas on how I can do a POST and send cookies in the same request?
I do see that headers get replaced in requestWithMethod in AFHTTPClient , anyway to control these headers?
I'm seeing this same behavior. If I do a login call using a POST, then print out the shared cookie values, I correctly see the session cookie set by my rails backend server. Then:
Am I dumb, is this expected behavior?
Sample code..
[[MyAFHTTPClient sharedClient] postPath:@"login"
parameters:parameters
success:^(AFHTTPRequestOperation *request, id JSON) {
NSLog(@"login success: %@", JSON);
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
for (NSHTTPCookie *cookie in cookies) {
// Here I see the correct rails session cookie
NSLog(@"cookie: %@", cookie);
}
// GET: works! server logs correctly show valid session
[[MyAFHTTPClient sharedClient] getPath:@"things"
parameters:[NSDictionary dictionary]
success:^(AFHTTPRequestOperation *request, id JSON) {
// Succeeds because session available
NSLog(@"things GET success: %@", JSON);
}
failure:^(AFHTTPRequestOperation *request, NSError *error) {
NSLog(@"things GET failure: %@", error);
}
];
// POST: fails! server logs show no session
[[MyAFHTTPClient sharedClient] postPath:@"things"
parameters:[NSDictionary dictionary]
success:^(AFHTTPRequestOperation *request, id JSON) {
NSLog(@"things POST success: %@", JSON);
}
failure:^(AFHTTPRequestOperation *request, NSError *error) {
// Fails because session not available
NSLog(@"things POST failure: %@", error);
}
];
}
failure:^(AFHTTPRequestOperation *request, NSError *error) {
NSLog(@"login failure: %@", error);
}
];
Cookies are handled entirely by the Foundation URL Loading system, upon which AFNetworking is built. You have complete control over the behavior of cookies in requests by configuring NSMutableURLRequest (setHTTPShouldHandleCookies) and NSHTTPCookieStorage accordingly.
Thanks @mattt. I had already been inspecting NSHTTPCookieStorage and the URLRequest to no avail. Turns out the behavior was a result of stock CSRF protection on a new rails backend (protect_from_forgery). Nothing to see here..
My sample code
//
NSURL *dataUrl = [NSURL URLWithString:path relativeToURL:url];
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:dataUrl];
NSDictionary *sheaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
__strong NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:dataUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.f];
[request setHTTPMethod:@"POST"];
[request addValue:@"iOS" forHTTPHeaderField:@"User-Agent"];
[request setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:[AFQueryStringFromParametersWithEncoding(paramters, NSUTF8StringEncoding) dataUsingEncoding:NSUTF8StringEncoding]];
[request setAllHTTPHeaderFields:sheaders];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
_operation = operation;
[operation start];
I was writing mock server and at some point, experienced same problem.
Cookies were not attached with first POST request.
After reading this article,
solution was to add "X-Request-URL" header for each server response.
Most helpful comment
Cookies are handled entirely by the Foundation URL Loading system, upon which AFNetworking is built. You have complete control over the behavior of cookies in requests by configuring
NSMutableURLRequest(setHTTPShouldHandleCookies) andNSHTTPCookieStorageaccordingly.