Writing library for Twitter, where am I going wrong? - php

I'm writing a library to connect to Twitter that uses Requests for PHP. I'm not sure, but I don't think that I'm building the OAuth correctly because I can't authenticate. I've double-checked it, and checked it against another existing library but still can't seem to get it right.
The code is here.
The idea is you instantiate the service, send it config parameters, and before it does the request, it generates the 'Authorization: OAuth xxx' header and adds it to said request.
$twitter = array(
'consumer_key' => '',
'consumer_secret' => '',
'access_token' => '',
'access_token_secret' => '',
'screen_name' => '_hassankhan',
'api_url' => 'https://api.twitter.com/1.1/'
);
$service = new OAuth1AService('Twitter', $twitter['api_url']);
$service->config($twitter);
$service->doGet(
'statuses/user_timeline.json',
array(
'screen_name' => '_hassankhan',
'include_entities' => 'true'
),
array(),
'raw'
);
print($service->getResult());

I would really recommend you to use one of the already made libraries like tmhOAuth which make it really easy to interact with the twitter api.
As for your problem, seems you don't sign your request correctly. At least I could not easily find out if you include all request parameters to create the signature.
The oauth_signature parameter contains a value which is generated by
running all of the other request parameters and two secret values
through a signing algorithm.
Creating the signature is described in this document: https://dev.twitter.com/docs/auth/creating-signature .

Related

Azure/Microsoft Identity Platform - Cannot Retrieve Access Token from Token Endpoint (PHP)

I'm trying to write a custom web app that utilizes the Microsoft Identity Platform to authenticate and authorize users. I'm able to successfully authenticate when calling the /authorize endpoint, and I have access to the "code" token that is returned.
I am now trying to retrieve my access token so that I can make calls to the APIs. Whenever I submit a POST request to the /token endpoint, the server returns a 400 Bad Request error. The header information that is provided contains no valuable information for troubleshooting and there is no JSON response returned so I have no idea where or what the issue is.
I'm making my call as follows:
$clientId = '00000000-0000-0000....'; // Omitted
$tenantId = '00000000-0000-0000....'; // Omitted
$grantType = 'authorization_code';
$scope = urlencode('User.Read');
$code = '......' // Obtained from authentication
$redirect_uri = 'http://localhost/smp/auth/handle';
$clientSecret = '...' // Omitted, set up in Azure App registrations under Certificates and secrets
$resource = 'api://00000000-0000-0000....'; // Omitted, set up in Azure App registrations under Overview -> App ID URI
$url = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
$parameters = [
'client_id' => $clientId,
'grant_type' => $grantType,
'scope' => $scope,
'code' => $code,
'redirect_uri' => $redirectUri,
'client_secret' => $clientSecret,
'resource' => $resource
];
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($parameters)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if (!$result) {
exit('an error has occured');
}
PHP returns a warning that reads the following: (tenant id has been omitted):
Warning: file_get_contents(https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0/token): Failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in C:\xampp\htdocs\smp\application\models\user-model.php on line 261
I've verified everything I can possibly think of.
The client and tenant ids are working (based on the successful authentication request).
The "code" is correctly retrieved from the authentication request.
Redirect Uri is the same as the one used for the authentication request.
I've tried with and without the client_secret variable. It is my understanding that this is actually required in my case.
I've tried with and without the resource variable, which is setup using the default Azure naming convention of "api://".
Please assist! I know I must be missing something but cannot figure it out. Perhaps permissions or additional setup within Azure? I'm not really sure what's wrong with my code/approach but Microsoft Identity Platform/OAuth isn't returning anything for me to work with and/or troubleshoot.
I've figured this out.
Firstly, I modified by $options variable to include the following:
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($parameters),
'ignore_errors' => true
]
];
Adding ignore_errors allowed me to see the returned JSON.
Next, it became apparent that my parameters were not being accepted because I was url-encoding all of them. My client secret, redirect uri, and client ids were all url encoded (this detail was hidden in my original post because it was just a small snippet of a much larger system). By undoing this encoding, my parameters all ended up being accepted. I suppose it makes sense because these values weren't being appended to a url but rather passed as POST values.
Lastly, the "resource" variable was not accepted (indeed, it wasn't required). Not sure if any of this is going to help anyone else but just in case, this was my fix.

PHP SoapClient with BasicAuth

I have a PHP script trying to connect to a WSDL.
I need to allow self signed AND give basic auth details.
Using SOAP UI, when I connect to the WSDL I am prompted for username / password.
I got this working.
I also found out that each request also requires basic auth (so on the request screen, I have to select Auth, then basic, enter same credentials as I used on the prompt).
How to I do this auth in PHP
As I said, I can connect, not a problem, I seem to kill the service or timeout if I try to make a request
<?php
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));
$data = array(
'columnA' => 'dataA',
'columnB' => 'dataB',
'columnC' => 'dataC');
$url = 'https://111.111.111.111:1234/dir/file';
$login = 'username';
$pwd = 'password';
$client = new soapClient(null, array(
'location' => $url,
'uri' => '',
'login' => $login,
'password' => $pwd,
'stream_context' => $context
));
echo "\n\r---connected---\n\r";
$result = $client ->requestName($data);
print_r($result);
?>
My output is
---connected---
Then it seems to hang.
I have tried wrapping it round a try catch and I had the same result.
Any suggestions??
From the Manual soapclient support the http basic auth.
For HTTP authentication, the login and password options can be used to
supply credentials. For making an HTTP connection through a proxy
server, the options proxy_host, proxy_port, proxy_login and
proxy_password are also available. For HTTPS client certificate
authentication use local_cert and passphrase options. An
authentication may be supplied in the authentication option. The
authentication method may be either SOAP_AUTHENTICATION_BASIC
(default) or SOAP_AUTHENTICATION_DIGEST.
$wsdl = "http://example/services/Service?wsdl";
$option = array(
"trace"=>1,
"login"=>"admin",
"password"=>"admin",
);
$client = new SoapClient($wsdl,$option);
But when I initiate the soapclient, it will throw this error
Exception: Unauthorized
I also have tried to put the auth in the url, like
$wsdl = "http://admin:admin#example/services/Service?wsdl";
But it also doesn't works.
Finally I solved it by add authentication to the option. The manual says the authentication default value is the basic auth, but only when I explicitly set it, it can work.
$option = array(
"trace"=>1,
"login"=>"admin",
"password"=>"admin",
"authentication"=>SOAP_AUTHENTICATION_BASIC
);
Try url encoding your username and password inside the url that you are using:
$url = 'http://'.urlencode('yourLogin').':'.urlencode('yourPassword').'#111.111.111.111:1234/dir/file';
Also I don't see you make use of the wsdl in your code example. You can always download a copy of the wsdl locally and then reference that local copy. You can download the wsdl anyway you want (with php, curl, manually).

Twitter's latest OAuth system conflict

I have a website..previously when I was uploading a new post in my blog..It was getting posted to twitter automatically. But since the new version of OAuth system..It no longer works...Can anybody help me to sort out what to change?
My code is :
'Twitter'=>array(
'enabled' => true, //set to false to shut off twitter integration
'username' => 'blogspott', //your twitter.com username
'password' => 'W3Sw9OpW6HvZYl', //your twitter.com pasword
'consumer_key' => 'TdQS15VHBdZNIrQ7RPqVQ',
'consumer_secret' => 'B2Xe5h3lHXVXUgoCAxgAIdJDTeBf6AywRoGiTwB7I',
'oauth_token' => '283508422-FkiIyZq2tpx1PQOyBLyWyomXY9OdMKxxSKGcg9d3',
'oauth_token_secret' => '548kxcZCvhytdRkJ405QeWONvMyXNEpSZszIMEYU4W4',
'tweet'=>'#%POST% for just %URL-TO-POST% %LINK%',
// Bit.ly / URL Shortening
// Within your Tweets, auto-append short URLs i.e., bit.ly/s8dJksm, to save on space.
// Sign up for an API account at http://bit.ly, and place the information
// for that account in the box below
'short_url'=>array(
'append_short_url'=>false,
'short_url_provider'=>'bit.ly', // current option: bit.ly only (default), more soon!
'bitly'=>array(
'login' => 'o_78ocugrkqtf',
'api_key' => 'R_734dbe3be47605c405f4e19ec35eb617'
),
)
),
I am using the right keys here..I've double checked it.
Twitter did not change its OAuth system recently. It is not concerned by the controversial Twitter API 1.1. So verify that you are doing it just like Twitter asks and that you do not use deprecated endpoints (Twitter removed some of them recently).

LinkedIn callback not working for certain URLs (using Zend Framework)

LinkedIn doesn't seem to like the idea of redirecting back to my test site.
This code directs me to the LinkedIn confirm page without any problems:
(This is pretty much a boilerplate example using Zend's OAuth)
$options = array(
'version' => '1.0',
'callbackUrl' => 'http://dev.local/',
'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken',
'userAuthorizationUrl' => 'https://api.linkedin.com/uas/oauth/authorize',
'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken',
'consumerKey' => [api],
'consumerSecret' => [secret]
);
$consumer = new Zend_Oauth_Consumer( $options );
// Start Requesting a LinkedIn Request Token
$token = $consumer->getRequestToken ();
// Store the LinkedIn Request Token
$_SESSION ['REQUEST_TOKEN'] = serialize ( $token );
// Redirect the Web User to LinkedIn Authentication Page
$consumer->redirect ();
However if my callback is http://dev.local/ it does not redirect, but if I specify a valid domain (like http://www.google.com) it redirects with no problem.
This behaviour happened recently (it was working fine until about a month ago). This is obviously a serious pain since I need to deploy code to be able to test anything.
Is this a problem people have experienced and has anyone found a way to get around?
it seems this is because LinkedIn changed their API, specifically how the api interacts with Oauth:
On the technical side, we've borrowed the OAuth 2.0 concept of the
"scope" parameter and incorporated it into our OAuth 1.0a and JS
Authentication flows.
Seems other apps, plugins and libraries are experiencing some difficulty with this as well.

Having trouble with the oauth_verifier for offline use in simple linkedin php

Disclaimer,
Please pardon grammatical syntax.
I'm using the simple linkedin php library that is offered on the linkedin's site. I have followed their instructions and have successfully collected the users oauth-token and oauth-secret. Those 2 pieces of information have been stored in a database. I would like to know how make an offline oauth call, but im having trouble finding more information on the oath-verifier. This is the code that i have so far.
include('../../php/linkedin/linkedin_3.2.0.class.php');
include '../../php/global.settings.php';
$API_CONFIG = array(
'appKey' => LINKEDIN_APP_KEY,
'appSecret' => LINKEDIN_APP_SECRET,
'callbackUrl' => NULL
);
$linkedin = new LinkedIn($API_CONFIG);
$linkedin->request_token = "4e1e5ede-1de4-4eba-ba33-d3d37cbe67ff -FAKE";
$linkedin->access_token = "82b2c333-1075-441b-a51f-657196bf507w -FAKE";
$search_response = $linkedin->search("?company-name=facebook&count=10");
var_dump($search_response);
Temporarily I'm inserting the keys their on my own trying to bottleneck the behavior. Again, the authentication was successful, but my attempt to make a call to the users profile when the user is offline is a failure. I believe it is because im missing the oauth-verifier, but i don't believe that the oauth-verifier is necessary to make an offline call.The code pretty much breaks without any errors (if that is possible). I Have not tempered with the linkedin library nor there are any errors in the global.settings.php.
If you have already stored the user's access token then all you need to do is feed the access token in to the library and make your calls. From the demo file, something along the lines of:
$API_CONFIG = array(
'appKey' => LINKEDIN_APP_KEY,
'appSecret' => LINKEDIN_APP_SECRET,
'callbackUrl' => NULL
);
$linkedin = new LinkedIn($API_CONFIG);
$linkedin->setToken(array(
'oauth_token' => $token,
'oauth_token_secret' => $secret
));
$search_response = $linkedin->search("?company-name=facebook&count=10");
var_dump($search_response);

Categories