-
Notifications
You must be signed in to change notification settings - Fork 7.6k
OAuth for Twitter
Category:Libraries::OAuth Category:Library::OAuth
This is another OAuth library I wrote. It should work with the twitter API and allow you to make authenticated calls as a particular user. It is very similar to a library I wrote that does OAuth for Google. The main differences are that this library defaults to using HMAC signing and there is no scope parameter. In theory this library can be used to authenticate with many services using the OAuth 1.0a spec. Twitter is probably the main site you would use it for though.
If you did want to have this work with another site you would change the host and uri constants specified at the top of the file.
This library has one dependency and that is on the oauth_helper I wrote it can be found at http://codeigniter.com/wiki/OAuth_Helper/ or at my blog linked below.
To load this library you would make a call like this
$params = array('key'=>'CONSUMER_KEY', 'secret'=>'CONSUMER_SECRET');
$this->load->library('twitter_oauth', $params);
Where the consumer key and consumer secret are the values that twitter provides for you. I would keep them in a config file so that you can easily access them.
After you have loaded the library there are only two methods to call and you must call then in the correct order. The first method will get a request token from twitter. The second will turn your request token into an access token.
First we need to get a request token.
$response = $this->twitter_oauth->get_request_token(site_url("user/twitter_access"));
The parameter you pass to this method is the full path to the token access step. The response given back by this method is an array and it contains two values the first has a key of "token_secret" and is the token secret that belongs to this request token. You need to store this value in the session or somewhere that you can then retrieve it in the twitter_access method. The second has a key of "redirect" and you need to then redirect to the url it specifies.
So the next lines should look like this
$this->session->set_userdata('token_secret', $response['token_secret']);
redirect($response['redirect']);
The user is now take to a page on twitter where they will be asked to allow or deny your application. If they deny it then they are saying they do not want your application to make api request on their behalf. If they allow it then the page will redirect back to your application to the page you specified in the parameter. It will also return some parameters in the URL these are the authorized request token and the token verifier. You can attempt to pull these out of the url and pass them into the get_access_token method but the library will also try to do that so you can probably just leave it be. There is however one parameter you need to supply, the token secret you had stored from the request method.
NOTE: You also have to reload the library.
Here is the code:
$params = array('key'=>'CONSUMER_KEY', 'secret'=>'CONSUMER_SECRET');
$this->load->library('twitter_oauth', $params);
$response = $this->twitter_oauth->get_access_token(false, $this->session->userdata('token_secret'));
The response array returned by this method contains all of the data you need including the access token and token secret as well as some additional data. You need to store the access token and token secret as they are what you use to make authenticated requests to twitter.
That's all here are the complete methods
function request_token()
{
$params = array('key'=>'CONSUMER_KEY', 'secret'=>'CONSUMER_SECRET');
$this->load->library('twitter_oauth', $params);
$response = $this->twitter_oauth->get_request_token(site_url("user/access_token"));
$this->session->set_userdata('token_secret', $response['token_secret']);
redirect($response['redirect']);
}
function access_token()
{
$params = array('key'=>'CONSUMER_KEY', 'secret'=>'CONSUMER_SECRET');
$this->load->library('twitter_oauth', $params);
$response = $this->twitter_oauth->get_access_token(false, $this->session->userdata('token_secret'));
$this->_store_in_db($response);
}
Here is the full library, if you would rather download a copy you can do so at my blog: http://jimdoescode.blogspot.com/2010/10/twitter-oauth-codeigniter-library-that.html
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Unlike what the name might indicate this library should work with most
* general OAuth implementations all you would need to change are the HOST,
* AUTHORIZE_URI, REQUEST_URI, and ACCESS_URI. To the appropriate values. I
* can't guarantee this will work but I know it works for twitter hence the
* name. Twitter only uses HMAC-SHA1 signing but this library can handle
* both RSA-SHA1 and HMAC-SH1. It defaults to HMAC and uses GET as its HTTP
* connection method. Both of these can be changed.
*
* Enjoy the OAuthy goodness <3 JimDoesCode.
**/
class twitter_oauth
{
const SCHEME = 'https';
const HOST = 'api.twitter.com';
const AUTHORIZE_URI = '/oauth/authorize';
const REQUEST_URI = '/oauth/request_token';
const ACCESS_URI = '/oauth/access_token';
//Array that should contain the consumer secret and
//key which should be passed into the constructor.
private $_consumer = false;
/**
* Pass in a parameters array which should look as follows:
* array('key'=>'example.com', 'secret'=>'mysecret');
* Note that the secret should either be a hash string for
* HMAC signatures or a file path string for RSA signatures.
*
* @param array $params
*/
public function twitter_oauth($params)
{
$this->CI = get_instance();
$this->CI->load->helper('oauth');
if(!array_key_exists('method', $params))$params['method'] = 'GET';
if(!array_key_exists('algorithm', $params))$params['algorithm'] = OAUTH_ALGORITHMS::HMAC_SHA1;
$this->_consumer = $params;
}
/**
* This is called to begin the oauth token exchange. This should only
* need to be called once for a user, provided they allow oauth access.
* It will return a URL that your site should redirect to, allowing the
* user to login and accept your application.
*
* @param string $callback the page on your site you wish to return to
* after the user grants your application access.
* @return mixed either the URL to redirect to, or if they specified HMAC
* signing an array with the token_secret and the redirect url
*/
public function get_request_token($callback)
{
$baseurl = self::SCHEME.'://'.self::HOST.self::REQUEST_URI;
//Generate an array with the initial oauth values we need
$auth = build_auth_array($baseurl, $this->_consumer['key'], $this->_consumer['secret'],
array('oauth_callback'=>urlencode($callback)),
$this->_consumer['method'], $this->_consumer['algorithm']);
//Create the "Authorization" portion of the header
$str = "";
foreach($auth as $key => $value)
$str .= ",{$key}=\"{$value}\"";
$str = 'Authorization: OAuth '.substr($str, 1);
//Send it
$response = $this->_connect($baseurl, $str);
//We should get back a request token and secret which
//we will add to the redirect url.
parse_str($response, $resarray);
//Return the full redirect url and let the user decide what to do from there.
$redirect = self::SCHEME.'://'.self::HOST.self::AUTHORIZE_URI."?oauth_token={$resarray['oauth_token']}";
//If they are using HMAC then we need to return the token secret for them to store.
if($this->_consumer['algorithm'] == OAUTH_ALGORITHMS::RSA_SHA1)return $redirect;
else return array('token_secret'=>$resarray['oauth_token_secret'], 'redirect'=>$redirect);
}
/**
* This is called to finish the oauth token exchange. This too should
* only need to be called once for a user. The token returned should
* be stored in your database for that particular user.
*
* @param string $token this is the oauth_token returned with your callback url
* @param string $secret this is the token secret supplied from the request (Only required if using HMAC)
* @param string $verifier this is the oauth_verifier returned with your callback url
* @return array access token and token secret
*/
public function get_access_token($token = false, $secret = false, $verifier = false)
{
//If no request token was specified then attempt to get one from the url
if($token === false && isset($_GET['oauth_token']))$token = $_GET['oauth_token'];
if($verifier === false && isset($_GET['oauth_verifier']))$verifier = $_GET['oauth_verifier'];
//If all else fails attempt to get it from the request uri.
if($token === false && $verifier === false)
{
$uri = $_SERVER['REQUEST_URI'];
$uriparts = explode('?', $uri);
$authfields = array();
parse_str($uriparts[1], $authfields);
$token = $authfields['oauth_token'];
$verifier = $authfields['oauth_verifier'];
}
$tokenddata = array('oauth_token'=>urlencode($token), 'oauth_verifier'=>urlencode($verifier));
if($secret !== false)$tokenddata['oauth_token_secret'] = urlencode($secret);
$baseurl = self::SCHEME.'://'.self::HOST.self::ACCESS_URI;
//Include the token and verifier into the header request.
$auth = get_auth_header($baseurl, $this->_consumer['key'], $this->_consumer['secret'],
$tokenddata, $this->_consumer['method'], $this->_consumer['algorithm']);
$response = $this->_connect($baseurl, $auth);
//Parse the response into an array it should contain
//both the access token and the secret key. (You only
//need the secret key if you use HMAC-SHA1 signatures.)
parse_str($response, $oauth);
//Return the token and secret for storage
return $oauth;
}
/**
* Connects to the server and sends the request,
* then returns the response from the server.
* @param <type> $url
* @param <type> $auth
* @return <type>
*/
private function _connect($url, $auth)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_SSLVERSION,3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth));
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
// ./system/application/libraries
?>
Have fun.