I'm a little confused about the flow I need to use if trying to connect to a remote Wordpress WP-API from another server (in this case another WP instance on the same server). I am using the PECL oAuth package, and most of the code I gathered up from the docs at https://secure.php.net/manual/en/class.oauth.php.
This is tied into a wordpress save hook like this, so every time someone saves a post on SITE A, it will attempt to send some info over to SITE B:
add_action( 'save_post', 'CrossPollinate_Save',10,3);
Inside CrossPollinate_Save is this:
$client_key = "....";
$client_secret = "....";
$request_token_endpoint = "http://..../oauth1/request";
$authorize_endpoint = "http://..../oauth1/authorize";
$access_endpoint = "http://..../oauth1/access";
$callback = $_SERVER['REQUEST_URI'];
$request_token = ""; //populated later
$request_token_secret = ""; //populated later
//STEP 1
$oauth = new OAuth($client_key, $client_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_AUTHORIZATION);
$request_token_info = $oauth->getRequestToken($request_token_endpoint);
if(!empty($request_token_info)) {
logToFile("Response from getRequestToken", $request_token_info);
} else {
logToFile("Failed fetching request token: ", $oauth->getLastResponse());
}
$request_token = $request_token_info["oauth_token"];
$request_token_secret = $request_token_info["oauth_token_secret"];
logToFile("request_token is: ", $request_token);
logToFile("request_token_secret is: ", $request_token_secret);
//STEP 2
$oauth->setToken($request_token, $request_token_secret);
$access_token_info = $oauth->getAccessToken($authorize_endpoint."?oauth_callback=".$callback);
if(!empty($access_token_info)) {
logToFile("Got access token! ", $access_token_info);
} else {
logToFile("Failed fetching access token: " . $oauth->getLastResponse());
}
I get an oauth_token and a oauth_token_secret from "step 1", great, that part works! When step 2 fires it ends up returning with a response that contains the markup for the login page. How do I tell oAuth to skip that step and just send the access token back to the redirect page?
I don't think there's a way around having to do the full 3-legged auth. I've found nothing to the contrary anyway and have just accepted that I'll have to do the redirect after getting the initial tokens.
Related
I'm having issues with Twitter API and understanding OAuth in general. I'm able to make request to pull information from my account with ease. The problem I'm having is with other users who would be using "Sign In with Twitter". Even though I am able to get other user information after they sign in, I'm unable to make separate future request with their information on other .php pages (I am not trying to pull info from MySQL). I can only get their information one time on the original .php page after they sign in and the page has loaded.
I will post some code but my main concerns/questions are -- is it possible to save user access token information (and re-use) or will I be needing to have the user sign in every time and authenticate just to pull information from their account? I am having trouble understanding this. What information can I save to make a request in the future on behalf of a user with out having to have them log in every time?
Code example:
require "autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
define('CONSUMER_KEY', 'my consumer key');
define('CONSUMER_SECRET', 'secret');
define('OAUTH_CALLBACK', 'API/Twitter/Twitter.php');
$access_token = 'beep boop boop beep';
$access_token_secret = 'super secret';
session_start();
if (isset($_SESSION['oauth_token'])) {
$oauth_token = $_SESSION['oauth_token'];
echo "<div style='background-color:white; width:100%;'>";
echo $oauth_token; echo "</div>";
unset($_SESSION['oauth_token']);
$connection = new Abraham\TwitterOAuth\TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
$params = array("oauth_verifier" => $_GET['oauth_verifier'], 'oauth_token' => $_GET['oauth_token']);
$access_token = $connection->oauth('oauth/access_token', $params);
$connection = new Abraham\TwitterOAuth\TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
$content = $connection->get('account/verify_credentials');
//Printing the profile data
//print_r($content);
$TimeLine = $connection->get("statuses/user_timeline", ["screen_name"=>$content->screen_name, "count"=>10]);
echo "<br><br><br>";
echo "<div style='width:100%; background-color:red; height:auto;'>";
print_r($connection);
echo "</div>";
//print_r($TimeLine);
} else {
$connection = new Abraham\TwitterOAuth\TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
$temporary_credentials = $connection->oauth('oauth/request_token', array("oauth_callback" => $callback));
$_SESSION['oauth_token'] = $temporary_credentials['oauth_token'];
$_SESSION['oauth_token_secret'] = $temporary_credentials['oauth_token_secret'];
$url = $connection->url('oauth/authenticate', array('oauth_token' => $temporary_credentials['oauth_token']));
}
What you need in order to maintain access to user information on behalf of them is the generated oAuth Token and oAuth Token Secret. In my particular case listed above, the steps should be
$connection = new Abraham\TwitterOAuth\TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, USER_oAuth_TOKEN, USER_oAuth_TOKEN_SECRET);
$content = $connection->get('account/verify_credentials');
You will need your own application CONSUMER_KEY and CONSUMER_SECRET. When someone signs in with Twitter, you have to save their oAuth Token and oAuth Token Secret. When you have this information (stored in a database), you can now make calls on behalf of the user for future request.
More into the specific problem I had listed above, I was not saving this information. I kept making new oAuth Tokens and Secrets.
I am using Twitter oAuth PHP Library (by Abraham Williams) for login-using-twitter for my web-application.
A.The Code model looks like this:
1.The Callback URL in twitter settings is set to :
http://example.com/entrypoint/twitterlogin.php
2.The twitterlogin.php file
<?PHP
if (empty($_GET['oauth_verifier'])){
$request_token = $twitteroauth->getRequestToken();
$_SESSION['onetime_oauth_token'] = $request_token['oauth_token'];
$_SESSION['onetime_oauth_token_secret'] = $request_token['oauth_token_secret'];
}
if (!empty($_GET['oauth_verifier']) && !empty($_SESSION['onetime_oauth_token']) && !empty($_SESSION['onetime_oauth_token_secret'])) {
$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET, $_SESSION['onetime_oauth_token'], $_SESSION['onetime_oauth_token_secret']);
$access_token = $twitteroauth->getAccessToken($_GET['oauth_verifier']);
$GoesToDB = $access_token['oauth_token'];
$GoesToDBS = $access_token['oauth_token_secret'];
$user_info = $twitteroauth->get('account/verify_credentials');
$GoesToDBArray = $user_info;
}else{
if ($twitteroauth->http_code == 200) {
//generates ~/authenticate?oauth_token=token
$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
//generates ~/authorize?oauth_token=token
//$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token'], false);//when and how to use this
exit(header("refresh:0;url=".$url));
} else {
//some error handler
}
}
?>
B.Expected behavior/results
If the user is first time user then generate authorize url (~/authorize?oauth_token=token)
Once the user has granted the permissions to the application generate authenticate url (~/authenticate?oauth_token=token) for future logins
C.Queries
Is the approach correct for the expected behavior
Do i have ask the user to use authorize url if he is an first time user, else use the authenticate url(similar the signin and signup)
Is there way to check if the user has authorized the application using (onetime_oauth_token or something else)
D.Thanking you in advance :) .. you are a life saviour.
Use this -
$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token'],TRUE);
I have this code to enable login with twitter in my site
<?php
require("twitter/twitteroauth.php");
require 'config/twconfig.php'; //CONTAINS CONSUMER SECRET AND CONSUMER KEY
session_start();
$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET);
$twitteroauth->host = "https://api.twitter.com/1.1/";
// Requesting authentication tokens, the parameter is the URL we will be redirected to
$request_token = $twitteroauth->getRequestToken('http://MY WEBSITE URL');
// Saving them into the session
$_SESSION['oauth_token'] = $request_token['oauth_token'];
$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];
// If everything goes well..
if ($twitteroauth->http_code == 200) {
// Let's generate the URL and redirect
$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
header('Location: ' . $url);
} else {
// It's a bad idea to kill the script, but we've got to know when there's an error.
die('Something wrong happened.'.$twitteroauth->http_code);
}
?>
I am using Abraham Williams twitter oauth. This worked well for a couple of weeks, but now
am getting a http_code of 0, which is not even listed in twitters list of error codes.
What could be the problem
Here is snippted i am using which works fine.
First make sure of the follownig
In dev twitter, you app can read / write
Refresh consumer key, Recreate access token.
If the folling is not working, the problem lies elsewhere t is something else!
see https://dev.twitter.com/search/apachesolr_search/HTTP%20CODE%200
Please read instructions, FOLLOW THEM and YOUR CODE will WORK
<?php
require_once('twitteroauth.php');
session_start();
/*
* INSTRUCTIONS!!!
* https://dev.twitter.com/
* create app
* https://dev.twitter.com/ TAB settings
* website: THE_URL_TO_YOUR_SCRIPT_WITH_THIS_CODE
* callback_url http://www.YOURDOMAIN.COM/
* Read, Write and Access direct messages !
* Allow this application to be used to Sign in with Twitter
* GO BACK TO DETAILS RECREATE / REFRESH - ACCESS TOKEN!
*/
$consumerKey = '******************';
$consumerSecret = '******************';
$oAuthToken = '*********************';
$oAuthSecret = '**************************';
// The TwitterOAuth instance
$twitteroauth = new TwitterOAuth($consumerKey, $consumerSecret);
// Requesting authentication tokens, the parameter is the URL we will be redirected to
$request_token = $twitteroauth->getRequestToken('http://DOMAIN.com/YOURLOGINSCRIPT.php');
// Saving them into the session
$_SESSION['oauth_token'] = $request_token['oauth_token'];
$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];
// If everything goes well..
if($twitteroauth->http_code==200){
// Let's generate the URL and redirect
$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
header('Location: '. $url);
} else {
// It's a bad idea to kill the script, but we've got to know when there's an error.
die('Something wrong happened.');
}
?>
Users on my website can login to Twitter and post their status on my website and twitter at once. I'm using https://github.com/abraham/twitteroauth to connect to Twitter. Login and posting is performed on different pages of website.
This is login script:
public function loginTwitter() {
$twitter = new TwitterOAuth(
$this->getContext()->params['social']['twitter']['consumerKey'],
$this->getContext()->params['social']['twitter']['consumerSecret']
);
$request_token = $twitter->getRequestToken($this->link('//User:connectFromTwitter'));
// Saving to session (Nette Framework)
$twitterSession = $this->getContext()->session->getSection('twSes');
$twitterSession->oauth_request_token = $token = $request_token['oauth_token'];
$twitterSession->oauth_request_token_secret = $request_token['oauth_token_secret'];
if ($twitter->http_code == 200) {
$requestLink = $twitter->getAuthorizeURL($token);
$this->redirectUrl($requestLink);
} else {
echo 'Error';
}
}
This is callback script (posting works right after user has been logged in):
public function twitterOauth() {
// $_GET parameter oauth_verifier
$oauthVerifier = $this->getParam('oauth_verifier');
// Session section
$twitterSession = $this->getContext()->session->getSection('twSes');
$twitter = new TwitterOAuth(
$this->getContext()->params['social']['twitter']['consumerKey'],
$this->getContext()->params['social']['twitter']['consumerSecret'],
$twitterSession->oauth_request_token,
$twitterSession->oauth_request_token_secret
);
$access_token = $twitter->getAccessToken($oauthVerifier);
$twitterSession->access_token = $access_token;
$user_info = $twitter->get('account/verify_credentials');
// Saving to DB to be able to post without login
$tm = new TwitterUserManager();
if (!$tm->isInDatabase($this->getUser()->getId())) {
$tu = new TwitterUser();
$tu->setUser($this->loggedUser);
$tu->setOauthProvider('twitter');
$tu->setOauthUid("'".$user_info->id."'");
$tu->setUsername("'".$user_info->screen_name."'");
$tu->setOauthToken("'".$access_token['oauth_token']."'"); // Saving the access token for further posting
$tu->setOauthSecret("'".$access_token['oauth_token_secret']."'");
$tm->persist($tu);
}
$twitter->post('statuses/update', array('status' => 'Hello ' . date('d.m.Y H:i:s'))); // <== HERE IT WORKS
$this->redirect('User:socialConnect'); // Redirect to another page
}
This is posting function (User posts from any page):
public function postToTwitter() {
$twitterSession = $this->getContext()->session->getSection('twitter');
$twitter = new TwitterOAuth(
$this->getContext()->params['social']['twitter']['consumerKey'],
$this->getContext()->params['social']['twitter']['consumerSecret'],
$twitterSession->access_token['oauth_token'],
$twitterSession->access_token['oauth_token_secret']
);
return $twitter->post('statuses/update', array('status' => 'Hello' . date('d.m.Y H:i:s')));
}
When I use posting function I get this error:
stdClass(2) {
request => "/1/statuses/update.json" (23)
error => "Could not authenticate you." (27)
}
Thanks for help in advance.
EDIT: Solution:
Use this to connect to Twitter (save all info into DB):
http://framework.zend.com/manual/1.12/en/zend.oauth.introduction.html
Use this to post from any page:
http://framework.zend.com/manual/1.12/en/zend.service.twitter.html
Nice example:
http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/
I always used the Zend-Framework-Component: http://framework.zend.com/manual/1.12/en/zend.service.twitter.html
I think it's simple and I could confirm, that it works. You just have to read through the tutorial (see link above).
I have spent a ton of hours on this and cannot for the life of me figure out what the problem is here. I am writing my own twitter web app. I downloaded the OAuth PHP Library which is what I am using. Everything was setup correctly.
I did Step 1 and "Acquire a Request Token". I got a correct response back with a token, token secret and callback confirmed of TRUE.
Now I proceeded to the next step of "Send User to Authorization" and passed along the oauth_token parameter to the request. The request got sent and redirects to the Twitter page, but when it gets there is is showing an error message of :
Exception Request failed with code 403:
Woah there!
This page requires some information that was not provided. Please return to the site that sent you to this page and try again … it was probably an honest mistake.
What is the problem?? The error message is not very helpful. According to Twitter 403 means the request was understood but denied. I am really stuck here and would appreciate the help with this one.
Here is what the code looks like (I have obviously replaces my token and secret keys with ########, so if anyone wanted to test this locally with their own keys, just replace the ######### values:
<?php
include_once "scripts/OAuth/OAuthStore.php";
include_once "scripts/OAuth/OAuthRequester.php";
// register at http://twitter.com/oauth_clients and fill these two
define("TWITTER_CONSUMER_KEY", "#############");
define("TWITTER_CONSUMER_SECRET", "#############");
define("TWITTER_OAUTH_HOST","https://api.twitter.com");
define("TWITTER_REQUEST_TOKEN_URL", TWITTER_OAUTH_HOST . "/oauth/request_token");
define("TWITTER_AUTHORIZE_URL", TWITTER_OAUTH_HOST . "/oauth/authorize");
define("TWITTER_ACCESS_TOKEN_URL", TWITTER_OAUTH_HOST . "/oauth/access_token");
define("TWITTER_PUBLIC_TIMELINE_API", TWITTER_OAUTH_HOST . "/statuses/public_timeline.json");
define("TWITTER_UPDATE_STATUS_API", TWITTER_OAUTH_HOST . "/statuses/update.json");
define('OAUTH_TMP_DIR', function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : realpath($_ENV["TMP"]));
// Twitter test
$options = array('consumer_key' => TWITTER_CONSUMER_KEY, 'consumer_secret' => TWITTER_CONSUMER_SECRET);
OAuthStore::instance("2Leg", $options);
try
{
// Obtain a request object for the request we want to make
$request = new OAuthRequester(TWITTER_REQUEST_TOKEN_URL, "POST");
$result = $request->doRequest(0);
parse_str($result['body'], $params);
list($token, $secret, $status) = explode('&', $result['body']);
// now make the request.
$request = new OAuthRequester(TWITTER_AUTHORIZE_URL, 'POST', $token);
$result = $request->doRequest();
}
catch(OAuthException2 $e)
{
echo "Exception " . $e->getMessage();
}
?>