6
votes

I'm using PECL OAuth when trying to authenticate to an API.

Sample Code:

<?php

$requestUri = 'http://openapi.lovefilm.com/oauth/request';

$consumerKey = 'MYCONSUMERKEY'; 
$consumerSecret = 'MYSECRET';

$oauth = new OAuth($consumerKey, $consumerSecret);

$oauth->setAuthType(OAUTH_AUTH_TYPE_AUTHORIZATION);
$oauth->setVersion('1.0');
$oauth->setTimestamp(mktime());


$oauth->enableDebug();

try
{
    $req = $oauth->getRequestToken($requestUri, 'oob');
    var_dump($req);
}
catch(OAuthException $e)
{
    print '<pre>';
    var_dump($e);

    var_dump($oauth->debugInfo);
}

?>

The specification they provide (http://developer.lovefilm.com/ - registration req) says I should POST a request similar to the one below:

POST /oauth/request_token HTTP/1.1 Host: openapi.lovefilm.com Authorization: OAuth oauth_callback="http%3A%2F%2Fyour-service.com%2Fsuccess", oauth_consumer_key="2blu7svnhwkzw29zg7cwkydn", oauth_nonce="5f38dbc02a97567965f14d", oauth_signature="sPSVmqN%2FXu9k0wlZxF0PqPZwYGo%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1278499295", oauth_version="1.0"

However when I use the the method:

$oauth->setAuthType(OAUTH_AUTH_TYPE_AUTHORIZATION);

The request that is generated is always a GET.

Can anyone help?

Thanks,

Ben

4

4 Answers

2
votes

Yes, according to the OAuth Specification, the request for Temporary Credentials (AKA "Request Token") and the request for Token Credentials (AKA "Access Token") MUST be submitted as an HTTP POST request, but the PECL OAuth extension seems to persistently use GET for getRequestToken() and getAccessToken()... by default.

There is an $auth_type parameter to OAuth::__construct() that accepts one of the following values:

  • OAUTH_AUTH_TYPE_AUTHORIZATION -- Submit OAuth parameters in the HTTP Authorization header of the request (and use a GET request by default).
  • OAUTH_AUTH_TYPE_URI -- Submit OAuth parameters in the request URI (i.e. query params in a GET request).
  • OAUTH_AUTH_TYPE_FORM -- Submit OAuth parameters as part of the HTTP POST body (in a POST request).
  • OAUTH_AUTH_TYPE_NONE -- Don't submit OAuth parameters at all, i.e. a "NoAuth" request (also GET by default).

From my experience, the fetch(), getRequestToken(), and getAccessToken() methods all respect this setting, which can also be set with OAuth::setAuthType() on an instance of the object. In practice, I set the auth type to OAUTH_AUTH_TYPE_FORM while performing the dance, then reset to default -- OAUTH_AUTH_TYPE_AUTHORIZATION -- to make resource requests.

0
votes

One way you can fix this, is to use OAuth::fetch instead of OAuth::getRequestToken and OAuth::getAccessToken.

$oauth = new OAuth('consumer_key', 'consumer_secret');
$oauth->fetch(
    'https://example.com/oauth/request_token', 
    array(), 
    OAUTH_HTTP_METHOD_POST
);
parse_str($oauth->getLastResponse(), $token_pair);
0
votes

Using OAUTH_AUTH_TYPE_FORM is only a workaround.

Pecl's oauth extension version 1.2.3 has a bug; getRequestToken and getAccessToken use GET requests instead of POST as the RFC wants.

You can work around this bug by passing OAUTH_HTTP_METHOD_POST as 3rd parameter to getRequestToken and 4th parameter to getAccessToken. Yes, those parameters are undocumented.


Version 1.2.4 of pecl/oauth will default to POST.

0
votes

It is a bit strange that they are asking specifically for POST when there is nothing in the post body in the example you gave! Does it work when it's a GET request? I'd be tempted to ping their tech support and ask what is going on there. If POST required, you may have to assemble the request manually rather than using the PECL, which is quite possible but quite tedious.