简体   繁体   中英

Twitter+oAuth engine returning 401 when trying to POST to twitter API 1.1

We are (and have been) using MGTwitterEngine + SAOauth with no problems until Twitters switch to API 1.1. We've made the required changes to work with 1.1 and almost everything works.
We can authenticate and GET status updates but we can't POST. We can't post a status update or friendship/create or destroy. We get a 401 error returned:

Error Domain=HTTP Code=401 "The operation couldn't be completed. (HTTP error 401.)

We have a valid access token since we can login and get statuses. Just can't seem to POST.

I assume you use SA_OAuthTwitterEngine. Try replacing the method _sendRequestWithMethod... with the following implementation:

- (NSString *)_sendRequestWithMethod:(NSString *)method 
                                path:(NSString *)path 
                     queryParameters:(NSDictionary *)params 
                                body:(NSString *)body 
                         requestType:(MGTwitterRequestType)requestType 
                        responseType:(MGTwitterResponseType)responseType
{

    BOOL isPOST = (method && [method isEqualToString:@"POST"]);

    NSString *fullPath = path;

    if (params) {
        fullPath = [self _queryStringWithBase:fullPath parameters:(isPOST ? nil : params) prefixed:YES];
    }

    // --------------------------------------------------------------------------------
    // modificaiton from the base clase
    // the base class appends parameters here
    // --------------------------------------------------------------------------------
    //    if (params) {
    //        fullPath = [self _queryStringWithBase:fullPath parameters:params prefixed:YES];
    //    }
    // --------------------------------------------------------------------------------

    NSString *urlString = [NSString stringWithFormat:@"%@://%@/%@", 
                           (_secureConnection) ? @"https" : @"http",
                           _APIDomain, fullPath];
    NSURL *finalURL = [NSURL URLWithString:urlString];
    if (!finalURL) {
        return nil;
    }

    // --------------------------------------------------------------------------------
    // modificaiton from the base clase
    // the base class creates a regular url request
    // we're going to create an oauth url request
    // --------------------------------------------------------------------------------
    //    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:finalURL 
    //                                                              cachePolicy:NSURLRequestReloadIgnoringCacheData 
    //                                                          timeoutInterval:URL_REQUEST_TIMEOUT];
    // --------------------------------------------------------------------------------

    OAMutableURLRequest *theRequest = [[[OAMutableURLRequest alloc] initWithURL:finalURL
                                                                       consumer:self.consumer 
                                                                          token:_accessToken 
                                                                          realm: nil
                                                              signatureProvider:nil] autorelease];
    if (method) {
        [theRequest setHTTPMethod:method];
    }
    [theRequest setHTTPShouldHandleCookies:NO];

    // Set headers for client information, for tracking purposes at Twitter.
    [theRequest setValue:_clientName    forHTTPHeaderField:@"X-Twitter-Client"];
    [theRequest setValue:_clientVersion forHTTPHeaderField:@"X-Twitter-Client-Version"];
    [theRequest setValue:_clientURL     forHTTPHeaderField:@"X-Twitter-Client-URL"];

    NSMutableArray *oauthParams = [NSMutableArray array];

    for (id key in params) {
        id value = [params objectForKey:key];
        [oauthParams addObject:[OARequestParameter requestParameterWithName:key value:value]];
    }

    [theRequest setParameters:oauthParams];

    // --------------------------------------------------------------------------------
    // modificaiton from the base clase
    // our version "prepares" the oauth url request
    // --------------------------------------------------------------------------------
    [theRequest prepare];

    // Create a connection using this request, with the default timeout and caching policy, 
    // and appropriate Twitter request and response types for parsing and error reporting.
    MGTwitterHTTPURLConnection *connection;
    connection = [[MGTwitterHTTPURLConnection alloc] initWithRequest:theRequest 
                                                            delegate:self 
                                                         requestType:requestType 
                                                        responseType:responseType];

    if (!connection) {
        return nil;
    } else {
        [_connections setObject:connection forKey:[connection identifier]];
        [connection release];
    }

    return [connection identifier];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM