0

I've been working on an all that uses the full OAuth app flow, and I have been running into an issue where I only get back a 401 = "Invalid or expired token" error. I've checked my request with the documentation, and everything looks correct, and I'm stumped. Below is the details of my request.

URL
https://api.twitter.com/1.1/oauth/access_token

HTTP Method
POST

Headers
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_consumer_key="CONSUMER_API_KEY", oauth_nonce="B4D43B0C-A348-4EB6-9C0B-8B0F4FE8", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1397724299", oauth_version="1.0", oauth_token="TOKEN_FROM_REQUEST_TOKEN_API", oauth_signature="ulYIzTacwC%2FeGUdoCPYsrFEqg4A%3D"

HTTP Body
oauth_verifier=OAUTH_VERIFIER_FROM_REQUEST_TOKEN_API

I have no issues getting the oauth/request_token API to work, and I have appropriately set the permissions in Twitter's app settings. Does anyone have any idea what's going on with this?

Thanks for any help you all may be able to offer.

-- UPDATE --

Another thing to note is that I'm using the STTwitter library to make the requests. It did not have a built-in method to handle the oauth/authorize or oath/authenticate API methods so I'm using the code below.

// get request token, and present login screen
STTwitterAPI *twitter = [STTwitterAPI twitterAPIWithOAuthConsumerKey:twitterApiKey consumerSecret:twitterApiSecret];
[twitter postTokenRequest:^(NSURL *url, NSString *oauthToken)
{
    authWebViewController = [[TWAuthWebViewController alloc] init];
    authWebViewController.url = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.twitter.com/oauth/authorize?oauth_token=%@", oauthToken]];

    authWebViewController.completion = ^(TWAuthWebViewController *authViewController, NSURL *oauthCallbackURL)
    {
        // get the request token and verifier from the URL
        NSString *oauthToken = [TWLoginBusiness getOAuthTokenFromURL:oauthCallbackURL];
        NSString *oauthVerifier = [TWLoginBusiness getOAuthVerifierFromURL:oauthCallbackURL];

        // get user data with the oauth token
        [twitter postResource:@"oauth/access_token"
                baseURLString:@"https://api.twitter.com/1.1"
                   parameters:@{@"oauth_verifier" : oauthVerifier}
          uploadProgressBlock:nil
        downloadProgressBlock:nil
                 successBlock:^(NSDictionary *rateLimits, id response)
        {
            NSLog(@"Reponse: %@", response);
            completion(nil, nil);

        } errorBlock:^(NSError *error)
        {
            NSLog(@"Error: %@", error);
            completion(nil, error);
        }];
    };

    presentAuthController(authWebViewController);

} oauthCallback:twitterApiCallback errorBlock:^(NSError *error)
{
    completion(nil, error);
}];

One last note. The part that actually displays the web view controller is not listed here. I wanted to keep the code snippet here focused on the actual API methods, and not the UI logic. Just be assured that the line right after authWebViewController.url.... displays the web view, and then the completion block is called after the user completes the authentication on the Twitter web page. Also the two methods getOauthTokenFromURL and getOauthVerifierFromUrl do in fact return the correct token and verifier. The STTwitter library actually saves out the token it's self, so that is why it's not manually passed into the logic below. The logic generates the request above.

Thanks

miken.mkndev
  • 1,821
  • 3
  • 25
  • 39
  • Have you checked that your computer's system time is accurate? If it's a few minutes out, it can cause authentication problems. – Terence Eden Apr 17 '14 at 10:45
  • I haven't yet, but that is a good suggestion as I was messing around with my date/time the other day testing stuff on a different app. I'll give that a look and report back here. Thanks for the suggestion:) – miken.mkndev Apr 17 '14 at 11:27
  • Just tried, and still no luck. The time on my computer is set correctly but I'm still getting the 401 "Invalid or Expired Token" issue. Any thoughts? – miken.mkndev Apr 17 '14 at 11:46

1 Answers1

1

The full OAuth flow is already implemented in STTwitter library.

Check out iOS demo for a working example of web-based authentication through Safari.

What you are trying to do here is a web-based authentication inside the application.

Although it is totally feasible, I did not include this workflow in the demo project because it is considered a bad practice.

Indeed, the point of OAuth is that the user does not want to enter her Twitter credentials in your own application, but asks Twitter to send your app dedicated OAuth tokens instead.

Let me know if you need more help with STTwitter.

nst
  • 3,862
  • 1
  • 31
  • 40
  • Hi, thanks for the info there. I did not see the demo and will take a look. I completely agree with your comment about including web-based authentication inside of an app as bad practice, however I have a client whom I'm building this for who's dead-set on the application never opening Safari. Regardless, I will take a look at the demo and see if I am able to assimilate it into my codebase. Thanks so much for the help! – miken.mkndev Apr 17 '14 at 14:01
  • Ok, using the method postTokenRequestWithPIN worked perfectly. When I first saw that method I thought it was for the newer Twitter PIN authorization that actually uses the PIN that Twitter returns when there is no callback URL. Turns out this'll work for both. Regardless, thanks for all the help buddy! – miken.mkndev Apr 17 '14 at 14:16
  • It seems that Apple rejected an app using STTwitter with authentication through Safari https://twitter.com/adamontherun/status/514561744304209921 so I added the webview-inside-app flow into the sample project https://github.com/nst/STTwitter/blob/master/demo_ios/STTwitterDemoIOS/ViewController.m#L66-L75 – nst Sep 26 '14 at 10:41