我在服务器上发送第一个请求以获取 cookie:
NSString* request = [NSString stringWithFormat:@"%@",SERVER_ADDRESS1];
responseData = [[NSMutableData data] retain];
NSURLRequest *urlrequest = [NSURLRequest requestWithURL:[NSURL URLWithString:request]];
[[NSURLConnection alloc] initWithRequest:urlrequest delegate:self];
在我们设置属性(cookies 和 crsf 令牌)之后:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
NSDictionary *fields = [HTTPResponse allHeaderFields];
self.cookies = [fields valueForKey:@"Set-Cookie"];
if (self.cookies){
NSString *crsf = [NSString stringWithString:[[self.cookies componentsSeparatedByString:@";"] objectAtIndex:0]];
NSString *rescrsf = [NSString stringWithString:[[crsf componentsSeparatedByString:@"="] objectAtIndex:1]];
self.cookies_csrf = rescrsf;
}
}
在我们打印响应并发送第二个请求之后:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *dump = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
NSLog(@"data: %@", dump);
self.namesArray = [dump componentsSeparatedByString:@"\n"];
[connection release];
[dump release];
NSURL *url = [NSURL URLWithString:@"https://servername/login/"];
NSString *postBodyStr = [SKUtils reqBodyCreateNewUsername:@"demo" password:@"123" check:@"1"];
NSData *postBody = [postBodyStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postBody length]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:self.cookies forHTTPHeaderField:@"Cookie"];
[request setValue:self.cookies_csrf forHTTPHeaderField:@"X-CSRFToken" ];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postBody];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
这一刻非常有趣:第二次请求后的响应看起来像带有 403 错误的 html 页面:
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
我做错了什么?
PS。SKUtils 的其他方法:
+ (NSString *)reqBodyCreateNewUsername:(NSString *)username password:(NSString *)pass check:(NSString *)ch {
NSArray *keys = [NSArray arrayWithObjects:@"username",@"password",@"mobile", nil];
NSArray *values = [NSArray arrayWithObjects:username, pass,ch, nil];
NSDictionary *params = [NSDictionary dictionaryWithObjects:values forKeys:keys];
return [SKUtils generateURLForActivity:nil hostName:NULL andParams:params];
}
+ (NSString *)generateURLForActivity:(NSString *)activityName hostName:(const char *)host andParams:(NSDictionary *)params {
NSMutableDictionary *fullParams = [[[NSMutableDictionary alloc] initWithDictionary:params] autorelease];
NSMutableString *urlStr = [[[NSMutableString alloc] init] autorelease];
if (host != NULL) {
[urlStr appendFormat:@"%s", host];
}
if (activityName != nil) {
[urlStr appendFormat:@"%@?", activityName];
}
NSArray *allKeys = [fullParams allKeys];
for (int paramIndex = 0; paramIndex < [allKeys count]; paramIndex++) {
NSString *curKey = [allKeys objectAtIndex:paramIndex];
id obj = [fullParams objectForKey:curKey];
if ([obj isKindOfClass:[NSString class]]) {
[urlStr appendFormat:@"%@=%@&", curKey, [SKUtils escapeString:[fullParams objectForKey:curKey] withEncoding:NSUTF8StringEncoding]];
}
else {
[urlStr appendFormat:@"%@=%@&", curKey, [fullParams objectForKey:curKey]];
}
}
NSString *result = [NSString stringWithFormat:@"%@", urlStr];
return result;
}
+ (NSString *)escapeString:(NSString *)string withEncoding:(NSStringEncoding)encoding
{
// CFSTR(":/?#[]@!$&’()*+,;=”)
NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)string,
NULL, (CFStringRef)@";/?:@&=$+{}<>,",
CFStringConvertNSStringEncodingToEncoding(encoding));
return [result autorelease];
}