Laravel Tumblr OAuth - Failed to Request Resource - php

I'm getting the following error:
I'm using artdarek's oauth-4-laravel but there doesn't seem to be much support in the Issues area.
My code is as follows:
public function tumblrLogin()
{
$oauth_token = Input::get( 'oauth_token' );
$oauth_verifier = Input::get( 'oauth_verifier' );
$tumblr = OAuth::consumer('Tumblr', 'http://30daychallenges.net/auth/tumblr/');
if ( !empty( $oauth_token ) && !empty( $oauth_verifier ) )
{
$token = $tumblr->retrieveAccessToken('Tumblr');
$tumblr->requestAccessToken( $oauth_token, $oauth_verifier, $token->getRequestTokenSecret() );
$result = json_decode( $tumblr->request('user/info'), true );
dd($result);
}
else
{
// get request token
$token = $tumblr->requestRequestToken();
// get Authorization Uri sending the request token
$url = $tumblr->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
return Redirect::to( (string)$url );
}
}
The error looks like it's coming from
$token = $tumblr->requestRequestToken();
But I can't see why - anyone experienced this error before?

Oh my. I feel like such an idiot.
In /app/config/packages/artdarek/oauth-4-laravel/config.php I had the credentials in the array, however the array keys were consumer_key and consumer_secret, as Tumblr's API had suggested.
The oauth-4-laravel package expects these to be client_id and client_secret uniformly, so this is my bad.

Related

Getting the acess token from Guzzle Oauth authentication

I'm currently trying to develop a connection to the Reddit api through Oauth using Guzzle. I get to the point where I authenticate in Reddit, then I get to the authorization token, but I can't take the access token from the Guzzle response so I can set it as a cookie and using on subsequent requests. My current code looks like this:
public function __construct(){
if(isset($_COOKIE['reddit_token'])){
$token_info = explode(":", $_COOKIE['reddit_token']);
$this->token_type = $token_info[0];
$this->access_token = $token_info[1];
} else {
if (isset($_GET['code'])){
//capture code from auth
$code = $_GET["code"];
//construct POST object for access token fetch request
$postvals = sprintf("code=%s&redirect_uri=%s&grant_type=authorization_code",
$code,
redditConfig::$ENDPOINT_OAUTH_REDIRECT);
//get JSON access token object (with refresh_token parameter)
$token = self::runCurl(redditConfig::$ENDPOINT_OAUTH_TOKEN, $postvals, null, true);
//store token and type
if (isset($token->access_token)){
$this->access_token = $token->access_token;
$this->token_type = $token->token_type;
//set token cookie for later use
$cookie_time = 60 * 59 + time(); //seconds * minutes = 59 minutes (token expires in 1hr)
setcookie('reddit_token', "{$this->token_type}:{$this->access_token}", $cookie_time);
}
} else {
$state = rand();
$urlAuth = sprintf("%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&state=%s",
redditConfig::$ENDPOINT_OAUTH_AUTHORIZE,
redditConfig::$CLIENT_ID,
redditConfig::$ENDPOINT_OAUTH_REDIRECT,
redditConfig::$SCOPES,
$state);
//forward user to PayPal auth page
header("Location: $urlAuth");
}
}
This is my authentication flow. The I have the runCurl method that is going to make the guzzle requests:
private function runCurl($url, $postVals = null, $headers = null, $auth = false){
$options = array(
'timeout' => 10,
'verify' => false,
'headers' => ['User-Agent' => 'testing/1.0']
);
$requestType = 'GET';
if ($postVals != null){
$options['body'] = $postVals;
$requestType = "POST";
}
if ($this->auth_mode == 'oauth'){
$options['headers'] = [
'User-Agent' => 'testing/1.0',
'Authorization' => "{$this->token_type} {$this->access_token}"];
}
if ($auth){
$options['auth'] = [redditConfig::$CLIENT_ID, redditConfig::$CLIENT_SECRET];
}
$client = new \GuzzleHttp\Client();
$response = $client->request($requestType, $url, $options);
$body = $response->getBody();
return $body;
}
The problem resides here, the getBody() method returns a stream, and if I use getBody()->getContents() I get a string, none of which can help me.
Any idea on how can I get the access token so I can finish the authentication process?
To answer the question itself - you just need to cast $body to string. It should be a json, so you will also need to json_decode it to use it as an object in the code above. So instead of return $body; in your runCurl, you need to do:
return json_decode((string)$body);
I would recommend to use the official client tho. The code in the question has some unrelated issues, which will make it costy to maintain.

Wordpress invalidate cf7 after api call

Here's my issue, I have contact form 7 for wordpress installed and during the wpcf7_before_send_mail I make a call to an API, I need to invalidate the form if the API returns an error then I need to invalidate the request and return the error passed back from the API call.
I set a flag to false on API failure and the error message is also stored but my form is going through as success despite the failure I induce.
add_action("wpcf7_before_send_mail", "wpcf7_send_contact_builder");
function wpcf7_send_contact_builder($form) {
$submission = WPCF7_Submission::get_instance();
$wpcf7_data = $submission->get_posted_data();
... api call and set $success to true if ok and false if not ...
if (!$success) {
$form->status = 'validation_failed (statuscode:' . $xml->status->statuscode[0] . ').';
$form->valid = false;
$form->response = $xml->status->statusdesc[0];
return $forml
}
}
I've also tried using:
$form->invalidate('validation_failed (statuscode:' . $xml->status->statuscode[0] . ').', $xml->status->statusdesc[0]);
But whichever way I am unable to prevent the success email being sent and the form validates as successful. Debugging proved that the !success in the if statement is working and the code contained is added to the variable. I also tried as if form was an array ($form['valid'] = false) but this also didn't work and the form submits as successful. Any ideas of what I'm missing here? I've omitted the code for the API call itself and the determining of the correct form id, both of these work correctly, only the form I'm after is parsed and the API call is returning the expected data.
I needed the same. After going through the CF7 plugin files, I found the following solution:
//To make it working, we must need at least CF7-v5.0;
add_action( 'wpcf7_before_send_mail', 'cf7_validate_api', 15, 3 );
function cf7_validate_api($cf7, &$abort, $submission){
if ( $cf7->id() !== 789 ) //CF7 post-id from admin settings;
return;
$errMsg = '';
//$submission = WPCF7_Submission::get_instance();
$postedData = $submission->get_posted_data();
//$postedData['more-data'] = 'something';
unset($postedData['not-sending-data']);
//-----API posting------
$url = "http://my-web.com/wp-admin/admin-ajax.php?action=get-something";
$username = 'apiUserName';
$password = 'apiUserPass';
$args = [
'headers' => [
'Authorization' => "Basic ".base64_encode( $username . ':' . $password ),
'Accept' => 'application/json; charset=utf-8', // The API returns JSON
//'Content-Type' => 'application/json; charset=utf-8'
],
'body' => $postedData
];
$response = wp_remote_post( $url, $args );
//------------------
if( is_wp_error( $response ) ){
$error_message = $response->get_error_message();
$errMsg = "Something went wrong:\n{$error_message}";
} else {
$response_body = wp_remote_retrieve_body( $response );
$data = json_decode( $response_body );
if( empty($data) || $data->status==0 ){ //API validation error!
$errMsg = $data->msg->title."\n".$data->msg->description;
}
}
if( $errMsg ){ //do not send mail;
//$cf7->skip_mail = true; //for older versions!
$abort = true; //==> Here, it is with 'called by reference' since CF7-v5.0 :)
$submission->set_status( 'validation_failed' );
//$submission->set_response( $cf7->message( 'validation_error' ) ); //msg from admin settings;
$submission->set_response( $cf7->filter_message($errMsg) ); //custom msg;
}
}
Hopefully, it will help someone. Happy Coding :)

Yahoo App Authentication Laravel

i am using this library
https://github.com/artdarek/oauth-4-laravel
here is my code
public function loginWithYahoo() {
// get data from input
$token = Input::get( 'oauth_token' );
$verify = Input::get( 'oauth_verifier' );
// get yahoo service
$yh = OAuth::consumer( 'Yahoo' );
// if code is provided get user data and sign in
if ( !empty( $token ) && !empty( $verify ) ) {
// This was a callback request from yahoo, get the token
$token = $yh->requestAccessToken( $token, $verify );
$xid = array($token->getExtraParams());
$result = json_decode( $yh->request( 'https://social.yahooapis.com/v1/user/'.$xid[0]['xoauth_yahoo_guid'].'/profile?format=json' ), true );
dd($result);
}
// if not ask for permission first
else {
// get request token
$reqToken = $yh->requestRequestToken();
// get Authorization Uri sending the request token
$url = $yh->getAuthorizationUri(array('oauth_token' => $reqToken->getRequestToken()));
// return to yahoo login url
return Redirect::to( (string)$url );
}
}.
I am getting following error.. can any one please give some hint???Thanks in advance
Call to undefined method OAuth\OAuth2\Service\Yahoo::requestRequestToken()
Use this code:
$url = $yh->getAuthorizationUri();
return redirect((string)$url);
instead of this code:
// get request token
$reqToken = $yh->requestRequestToken();
// get Authorization Uri sending the request token
$url = $yh->getAuthorizationUri(array('oauth_token' => $reqToken->getRequestToken()));
// return to yahoo login url
return Redirect::to( (string)$url );

Why am I getting "Failed to request resource" when posting to a users wall on Facebook?

I'm using artdarek/oauth-4-laravel so the user can login via Facebook and post to their feed. I'm able to login in via Facebook using the following bit of code
// get data from input
$code = Input::get( 'code' );
// get fb service
$fb = OAuth::consumer( 'Facebook' );
// check if code is valid
// if code is provided get user data and sign in
if ( !empty( $code ) ) {
$token = $fb->requestAccessToken( $code );
$_SESSION['facebook_access_token'] = $token->getAccessToken();
// Send a request with it
$user = json_decode( $fb->request( '/me' ), true );
...
And everything works as expected. In the App I also have a share button, but when I try and share I get the following error
{"error":{"type":"OAuth\\Common\\Http\\Exception\\TokenResponseException","message":"Failed to request resource.","file":"\/var\/www\/html\/myApp\/vendor\/lusitanian\/oauth\/src\/OAuth\/Common\/Http\/Client\/StreamClient.php","line":68}}
Here is the code that I'm using for posting
if ( isset($_SESSION['facebook_access_token']) ) {
$fb = OAuth::consumer( 'Facebook' );
// $user = json_decode( $fb->request( "/me?access_token={$_SESSION['facebook_access_token']}" ), true );
$postMessage = json_decode( $fb->request
(
'POST',
"/me/feed?access_token={$_SESSION['facebook_access_token']}",
array (
'message' => 'This is a test message'
)
),
true );
return $postMessage;
}
I know that the $_SESSION[] is set because I ran the commented out line first and it was returning what I expected. But the code for posting on the wall is giving me that error mentioned earlier.
Please help.
Thanks
I found the mistake ... The call is supposed to be as follows
$postMessage = json_decode( $fb->request
(
"/me/feed?access_token={$_SESSION['facebook_access_token']}",
'POST',
array (
'message' => 'This is a test message'
)
),
true );
The route is supposed to be first and then the POST.

How do I get the access_token from tumblr's official php client?

I've followed the directions posted in this stackoverflow question, but I am stuck.
I am using tumblr/tumblr.php from Github (the official "PHP client for the tumblr API").
I am also following directions here (which are actually for twitter), but those directions aren't tailored for the git library I am using.
I have a valid consumer key and secret.
From those I make a request and get oauth_token and oauth_token_secret like so:
$client = new Tumblr\API\Client($consumerKey,$consumerSecret);
$client->getRequestHandler()->setBaseUrl('https://www.tumblr.com/');
$req = $client->getRequestHandler()->request('POST', 'oauth/request_token', [
'oauth_callback' => '...',
]);
// Get the result
$result = $req->body->__toString();
print_r( $result );
Which gives me:
oauth_token=2C6f...MqSF&oauth_token_secret=HaGh...IJLi&oauth_callback_confirmed=true
Then I send the user to the http://www.tumblr.com/oauth/authorize?oauth_token=2C6f...MqSF, so they can allow access for the app. This redirects to: ...?oauth_token=2C6f...MqSF&oauth_verifier=nvjl...GtEa#_=_
And now in the final step I believe I am supposed to convert my request token to an access token. Is that right? I am doing something wrong:
$client = new Tumblr\API\Client($consumerKey,$consumerSecret);
$client->getRequestHandler()->setBaseUrl('https://www.tumblr.com/');
$req = $client->getRequestHandler()->request('POST', 'oauth/access_token', [
'oauth_token' => '2C6f...MqSF',
'oauth_verifier' => 'nvjl...GtEa'
]);
// Get the result
$result = $req->body->__toString();
print_r( $result );
because I get responses like this one:
oauth_signature [AqbbYs0XSZ7plqB0V3UQ6O6SCVI=] does not match expected value [0XwhYMWswlRWgcr6WeA7/RrwrhA=]
What is wrong with my last step?
I am not sure if I should even be sending oauth_verifier with the request. Is #_=_ supposed to be part of oauth_verifier? I wouldn't think so. I get signature errors for all the variations Ive tried.
Without the token and tokenSecret I can't make certain calls to the API. I get unauthorized 403 responses. Same when I use the token and token_secret from the second step. I'm pretty sure I need a new token/secret pair.
You're pretty close, you just are passing the oauth_token incorrectly in the last step, and skipping out on oauth_token_secret altogeter.
I've compiled this working code (which you can also now find posted on the Wiki at https://github.com/tumblr/tumblr.php/wiki/Authentication):
<?php
require_once('vendor/autoload.php');
// some variables that will be pretttty useful
$consumerKey = '<your consumer key>';
$consumerSecret = 'your consumer secret>';
$client = new Tumblr\API\Client($consumerKey, $consumerSecret);
$requestHandler = $client->getRequestHandler();
$requestHandler->setBaseUrl('https://www.tumblr.com/');
// start the old gal up
$resp = $requestHandler->request('POST', 'oauth/request_token', array());
// get the oauth_token
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// tell the user where to go
echo 'https://www.tumblr.com/oauth/authorize?oauth_token=' . $data['oauth_token'];
$client->setToken($data['oauth_token'], $data['oauth_token_secret']);
// get the verifier
echo "\noauth_verifier: ";
$handle = fopen('php://stdin', 'r');
$line = fgets($handle);
// exchange the verifier for the keys
$verifier = trim($line);
$resp = $requestHandler->request('POST', 'oauth/access_token', array('oauth_verifier' => $verifier));
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// and print out our new keys
$token = $data['oauth_token'];
$secret = $data['oauth_token_secret'];
echo "\ntoken: " . $token . "\nsecret: " . $secret;
// and prove we're in the money
$client = new Tumblr\API\Client($consumerKey, $consumerSecret, $token, $secret);
$info = $client->getUserInfo();
echo "\ncongrats " . $info->user->name . "!\n";

Categories