I am using Twitter to log users into to a website, which seems to be working up until I attempt to obtain a valid Access Token.
require("twitteroauth.php");
require 'twconfig.php';
session_start();
$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET);
$request_token = $twitteroauth->getRequestToken('http://****/tw_response.php');
$oauth_token = $request_token['oauth_token'];
$_SESSION['oauth_token'] = $oauth_token;
$oauth_token_secret = $request_token['oauth_token_secret'];
$_SESSION['oauth_token_secret'] = $oauth_token_secret;
if ($twitteroauth->http_code == 200) {
url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
header('Location: '.$url);
} else {
die('Something wrong happened.');
}
This seems to be working correctly, redirecting me to twitter to sign in and confirm access, after which it returns me to tw_response.php (my Callback url), with the following variables in the url:
http://example.com/login.php?oauth_token=sO3X...yj0k&oauth_verifier=Ip6T...gALQ
In tw_response.php I then try to get the Access Token, but it reports as invalid. I tried using var_dump
to view the content of the access token as follows:
require("twitteroauth.php");
require 'twconfig.php';
session_start();
$oauth_verifier = $_REQUEST['oauth_verifier'];
$oauth_token = $_SESSION['oauth_token'];
$oauth_token_secret = $_SESSION['oauth_token_secret'];
$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET, $oauth_token, $oauth_token_secret);
$access_token = $twitteroauth->getAccessToken($data['oauth_verifier']);
var_dump($access_token);
The result of the var_dump
ends in "invalid / expired Token":
array(8) {
["oauth_url"] => string(104) ""1.0" encoding="UTF-8"?>/oauth/access_token?oauth_consumer_key=ceE...9Dg"
["oauth_nonce"]=> string(32) "c52...d07"
["oauth_signature"]=> string(28) "ry7...Fcc="
["oauth_signature_method"]=> string(9) "HMAC-SHA1"
["oauth_timestamp"]=> string(10) "1359031586"
["oauth_token"]=> string(40) "sO3...j0k"
["oauth_verifier"]=> string(43) "Ip6...ALQ"
["oauth_version"]=> string(63) "1.0 Invalid / expired Token "
}
These tokens do not expire but can be revoked by the user at any time. Twitter allows you to obtain user access tokens through the 3-legged OAuth flow, which allows your application to obtain an access token and access token secret by redirecting a user to Twitter and having them authorize your application.
Generating access tokensLogin to your Twitter account on developer.twitter.com. Navigate to the Twitter app dashboard and open the Twitter app for which you would like to generate access tokens. Navigate to the "Keys and Tokens" page. Select 'Create' under the "Access token & access token secret" section.
If you experience an error message that states "Token Expired", this is letting you know the system has timed out and will need to be refreshed.
$access_token = $twitteroauth->getAccessToken($data['oauth_verifier']);
var_dump($access_token);
Where did $data
magically come from? You have the variable $oauth_verifier
, but keep in mind you don't need this if this is your registered callback URL.
Since you used an invalid variable inside getAccessToken
, it will return an invalid value back.
The correct way to use TwitterOAuth:
if (!isset($_GET["oauth_token"])) {
// set these values in a config file somewhere.
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
// append a ?. This is your callback URL if you specify something.
$credentials = $twitter->getRequestToken("http://example.com/test.php?");
// try and be a bit more elegant with the URL... This is a minimal example
$url = $twitter->getAuthorizeUrl($credentials);
echo $url;
// these are temporary tokens that must be used to fetch the new,
// permanent access tokens. store these in some way,
// session is a decent choice.
$_SESSION["token"] = $credentials["oauth_token"];
$_SESSION["secret"] = $credentials["oauth_token_secret"];
} else {
// use the user's previously stored temporary credentials here
$twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET,
$_SESSION["token"], $_SESSION["secret"]);
// uses the oauth_token (from the request) already.
// you store these credentials in your database (see below).
$credentials = $twitter->getAccessToken($_GET["oauth_verifier"]);
// just a printout of credentials. store these, don't display them.
echo "<pre>";
var_dump($credentials);
// valid credentials, provided you give the app access to them.
echo "</pre>";
}
I just use a single script for callbacks for ease of use; you can split the relevant sections into multiple scripts if you like (and you probably should).
Handily for your database, the credentials include the twitter user's username, too.
Edit: Twitter is now allocating 64bit integers for user IDs. You should store this as a string to ensure that you don't end up with mangled user IDs and collisions if you can't handle 64bit integers in every part of your application.
array(4) {
["oauth_token"]=>
string(50) "7041...wYupkS"
["oauth_token_secret"]=>
string(42) "O9ENq...21B2fk"
["user_id"]=> // user ID. always the same, never changes (store this as ID)
string(9) "..."
["screen_name"]=> // username. can change.
string(11) "..."
}
So, if you want to log users in through twitter, without explicitly giving them a login to your site, you could use $_SESSION
(I use databases for my logins, which is recommended if you want to save that state)
In the above script you would add this to the end of the else
block:
$_SESSION["token"] = $credentials["oauth_token"];
$_SESSION["secret"] = $credentials["oauth_secret"];
$_SESSION["username"] = $credentials["screen_name"];
You can also get the user's screen name and more from GET account/verify_credentials
, if you want to give them a user page (if you use javascript, grab their userid through id_str
here):
$user_array = $twitter->get("account/verify_credentials");
If your OAuth flow was working one day and failing the next, check your computer's clock. I was running a Vagrant box that somehow had its time set to the day before, which caused the Twitter API to return {"code":89,"message":"Invalid or expired token."}. This may also appear as 401 timestamp out of bounds. You can use this command to update your clock in Ubuntu:
sudo ntpdate time.nist.gov
Alternative method if ntpdate
isn't available on your system:
sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"
If one doesn't pay one will only be able to create the dev environment (sandbox).
As I have answered here:
Counts is only available to paid premium accounts, and one needs to pay for premium access.
Use this link to Apply for access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With