Twitter OAuth 1的POST请求无法正常工作。

8
我正在为iOS创建一个应用程序,我正在使用这个OAuth库。GET请求似乎工作正常,但是一旦我尝试进行POST请求,我就会收到以下错误消息:

[代码32] 无法验证您的身份。

现在我不太确定发生了什么,因为POST请求与GET请求非常相似。有什么想法是什么导致了这个错误吗?

这里是生成请求的代码:

+ (NSURLRequest *)preparedRequestForPath:(NSString *)path
                              parameters:(NSDictionary *)queryParameters
                              HTTPmethod:(NSString *)HTTPmethod
                              oauthToken:(NSString *)oauth_token
                             oauthSecret:(NSString *)oauth_token_secret
{
    if (!HTTPmethod
        || !oauth_token) return nil;



    NSMutableDictionary *allParameters = [self standardOauthParameters];
    allParameters[@"oauth_token"] = oauth_token;
    if (queryParameters) [allParameters addEntriesFromDictionary:queryParameters];

    NSString *parametersString = CHQueryStringFromParametersWithEncoding(allParameters, NSUTF8StringEncoding);

    NSString *request_url = API_URL;
    if (path) request_url = [request_url stringByAppendingString:path];
    NSString *oauth_consumer_secret = CONSUMER_SECRET;
    NSString *baseString = [HTTPmethod stringByAppendingFormat:@"&%@&%@", request_url.utf8AndURLEncode, parametersString.utf8AndURLEncode];
    NSString *secretString = [oauth_consumer_secret.utf8AndURLEncode stringByAppendingFormat:@"&%@", oauth_token_secret.utf8AndURLEncode];
    NSString *oauth_signature = [self.class signClearText:baseString withSecret:secretString];
    allParameters[@"oauth_signature"] = oauth_signature;

    NSString *queryString;
    if (queryParameters) queryString = CHQueryStringFromParametersWithEncoding(queryParameters, NSUTF8StringEncoding);
    if (queryString) request_url = [request_url stringByAppendingFormat:@"?%@", queryString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:request_url]];
    request.HTTPMethod = HTTPmethod;

    NSMutableArray *parameterPairs = [NSMutableArray array];
    [allParameters removeObjectsForKeys:queryParameters.allKeys];
    for (NSString *name in allParameters) {
        NSString *aPair = [name stringByAppendingFormat:@"=\"%@\"", [allParameters[name] utf8AndURLEncode]];
        [parameterPairs addObject:aPair];
    }
    NSString *oAuthHeader = [@"OAuth " stringByAppendingFormat:@"%@", [parameterPairs componentsJoinedByString:@", "]];
    [request setValue:oAuthHeader forHTTPHeaderField:@"Authorization"];

    if ([HTTPmethod isEqualToString:@"POST"]
        && queryParameters != nil) {
        NSData *body = [queryString dataUsingEncoding:NSUTF8StringEncoding];
        [request setHTTPBody:body];
    }

    return request;
}

编辑

代码的最后几行设置HTTP正文似乎引起了问题。当我删除这些行时

 NSData *body = [queryString dataUsingEncoding:NSUTF8StringEncoding];
 [request setHTTPBody:body];

除了在发送base64编码的图像等参数异常大时会失败之外,一切都正常...我应该怎么做才能解决这个问题?


你是使用同步还是异步的NSURLConnection来获取这个NSURLRequest? - ModernCarpentry
@ModernCarpentry 我正在异步请求。 - the_critic
@the_critic 这里的查询参数是什么? - Anurag Sharma
2个回答

1

好的...

我不确切知道原因是什么。 无法向非关注者发送私信。

API控制台怎么样?它可以测试Twitter API,也许对你有帮助。

首先,你可以正确地测试直接消息API,然后比较API控制台和你的代码之间的结果。


我能够发送消息,只是说罪魁祸首不可能是权限问题,因为如果我有直接消息访问权限,那么我肯定应该能够进行POST请求...但我要检查一下控制台,这可能会有所帮助,我将尝试并稍后回来。 - the_critic
当返回'request'时,您能否打印'queryString'和'request_url'?还有一个问题!当方法类型为'POST'时,'queryString'被UTF8编码两次以设置Body。 - Sung-Pil Lim
为什么不使用Twitter API Libraries呢?已经存在Objective-C库了。有任何原因吗? - Sung-Pil Lim
我正在使用一个库,这段代码来自于该库。如果我记录返回请求的正文 NSLog(@"body = %@", [[NSString alloc]initWithData:preparedRequest.HTTPBody encoding:NSUTF8StringEncoding]);,我会得到一个示例值 "body = id=336959346300829698"。 - the_critic
从Twitter开发者页面→主页→我的应用程序并进入您的应用程序的“设置”→“应用程序类型”→勾选“读取、写入和访问直接消息”权限后,尝试POST时出现401错误,但GET没有问题。 - Sung-Pil Lim
好的,请再看一下我的问题,我进行了编辑并得出结论,即HTTP正文是问题所在。然而,我必须将查询参数与HTTP正文一起发送,因为如果参数太大,请求将无法通过... 因此仍然存在一些小问题。 - the_critic

0

我通过添加以下HTTP头字段来解决问题:

[request setValue:@"api.twitter.com" forHTTPHeaderField:@"X-HostCommonName"];
[request setValue:@"api.twitter.com" forHTTPHeaderField:@"Host"];
[request setValue:@"https://api.twitter.com" forHTTPHeaderField:@"X-Target-URI"];
[request setValue:@"Keep-Alive" forHTTPHeaderField:@"Connection"];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接