How to keep OAuth settings a secret? - php

After creating my Twitter application, the following warning was displayed:
OAuth settings
Your application's OAuth settings. Keep the "Consumer secret" a
secret. This key should never be human-readable in your application.
How do I keep my "Consumer Secret" a secret?
Twitter_test.php (source: Jimbo)
// Set access tokens here
$settings = array(
'oauth_access_token' => "My Oauth Access Token",
'oauth_access_token_secret' => "My Oauth Access Token Secret",
'consumer_key' => "My Consumer Key",
'consumer_secret' => "My Consumer Secret"
);
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?username=somename';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
?>
TwitterAPIExchange (source: twitter-api-php)

I'd create a library integrated with the Twitter Api, and store the data in a config file in application/config/ as mentioned in given link.
To please Twitter, simply parse:
$this->load->library('encrypt');
echo $this->encrypt->encode('your given secret here');
Take the output, store it inside the config file, and when you're fetching it:
$this->load->library('encrypt');
$str_secret = $this->encrypt->decode($config['secret']);
Encryption
-Don't forget to set a key as described in this link.
Note that they demand you to do that for maximum security, in case someone would get control over your ftp or similiar. However if it can be decoded, it can be read. This isn't the ultimate solution, but simply a bit more reliable one.

You can save Consumer secret in database in serialize format and than unserialize while fetching and than use it.

consumer_secret is a secret key given by twitter when you sign up for the apis. You can keep it safe by putting twitter code in your library or any as such folder and make sure that folder is not directly accessible using browser url.
For example if you put twitter config.php in lib folder then it should not be accessible like this
www.somedomain.com/lib/config.php

Related

How to make a call with the Twitter V2 API

I'm using the below code to search Tweets with the query parameter. This works fine with the Twitter V1 API, but not with the V2, and after extensively reading their API documentation, I'm confused.
My first question is, do the V1 and V2 share the same authentication? i.e. can I make a call to the V2 with this code, assuming my end point url is correct which leads to the second question, if I can make a call to the V2 with the same auth as the V1, what's the correct end point? the notable differences so far is the query parameter which is "q" for the V1 and "query" for the V2. Then apparently the .json is not needed, but I tried both at the end of the V2 end point and still I get the same error:
stdClass Object ( [client_id] => 131XXXXXX [detail] => When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project. You can create a project via the developer portal. [registration_url] => https://developer.twitter.com/en/docs/projects/overview [title] => Client Forbidden [required_enrollment] => Standard Basic [reason] => client-not-enrolled [type] => https://api.twitter.com/2/problems/client-forbidden )
include ($_SERVER["DOCUMENT_ROOT"] . "/TwitterAPIExchange.php");
$settings = array(
'oauth_access_token' => "xxx",
'oauth_access_token_secret' => "xxx",
'consumer_key' => "xxx",
'consumer_secret' => "xxx"
);
//$url = "https://api.twitter.com/1.1/search/tweets.json";
$url = "https://api.twitter.com/2/tweets/search/recent";
$requestMethod = "GET";
// V1
//$getfield = '?q=bitcoin';
// V2
$getfield = '?query=bitcoin';
$twitter = new TwitterAPIExchange($settings);
$response = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
$tweets = json_decode($response);
print_r($tweets);
EDIT:
Looks like the V1 and V2 can share the same auth: https://developer.twitter.com/en/docs/twitter-api/tweets/search/migrate/standard-to-twitter-api-v2
OAuth 1.0a User Context and OAuth 2.0 Bearer Token authentication
The v1.1 search/tweets and the Twitter API v2 recent search endpoint support both OAuth 1.0a User Context and OAuth 2.0 Bearer Token.
Therefore, if you were previously using the standard v1.1 search endpoint you can continue using the same authentication method if you migrate to the Twitter API v2 version.
First you have to add the app you’re using to a “Project” on the Developer dashboard. This step is necessary to be able to call v2 endpoints see: https://developer.twitter.com/en/docs/projects/overview
I got this answer from the twitter community forum and now it works fine with the code posted in my question above.

Twitter webhook registration error | {"errors":[{"code":32,"message":"Could not authenticate you."}]}

when I try to register the twitter web-hook, api returns the error message "Could not authenticate you".
I am using the below php wrapper for twitter api v1.1.
twitter-api-php
$settings = array(
'oauth_access_token' => $accesstoken,
'oauth_access_token_secret' => $accesstokensecret,
'consumer_key' => $consumerkey,
'consumer_secret' => $consumersecret
);
$url = 'https://api.twitter.com/1.1/account_activity/all/msgdev/webhooks.json?url=https://myapp.com/twitterwebhook.php';
$requestMethod = 'POST';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->buildOauth($url, $requestMethod)->performRequest();
I am able to send message. But not able to create webhook.
Created developer account and got api access, also created twitter app in apps.twitter.com
You can fix this issue by doing a url-encode on your URL parameter. Refer the sample code on how we are doing it in ruby.
response = #twitter_api.post('https://api.twitter.com/1.1/account_activity/all/chatwootdev/webhooks.json?url=https%3A%2F%2Fchatwoot.com%2F16b66d68-c9f9-4c2e-8caa-4244cff8b483', nil, HEADERS)
Also note that you will need to implement a CRC check at your webhook url before you start getting the events from twitter. If the CRC is not implemented. you will be recieveing 214 error code.
ref: getting started with twitter accounts subscription api

Twitter oauth2/invalidate_token error "Unable to verify your credentials", "authenticity_token_error"

I'm getting an error when trying to use Twitter oauth2/invalidate_token. The error is: {"errors":[{"code":99,"message":"Unable to verify your credentials","label":"authenticity_token_error"}]}
I'm using the TwitterAPIExchange.php wrapper which you can find here and here. The framework is Codeigniter 3.0 and this code is within a method that is called by AJAX (but I don't think either of those matter to this).
Here is my code:
$settings = array(
'oauth_access_token' => $this->session->userdata('oauth_token'),
'oauth_access_token_secret' => $this->session->userdata('oauth_token_secret'),
'consumer_key' => TWITTER_CONSUMER_KEY,
'consumer_secret' => TWITTER_CONSUMER_SECRET);
$twitter = new TwitterAPIExchange($settings);
$url = 'https://api.twitter.com/oauth2/invalidate_token';
$requestMethod = 'POST';
$postfields = array('access_token' => $this->session->userdata('oauth_token'));
$response_str = $twitter->buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest();
$response_arr = [];
parse_str($response_str, $response_arr);
The contents of $response_str is the error. The contents of the oauth_token and oauth_token_secret are the user's not the app's.
As a test, when I replace the call to oauth2/invalidate_token with a GET to statuses/user_timeline.json, it works fine. So it seems the settings are correct. If I replace the relevant lines above, leave the settings alone, this works fine:
$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$getfield = '?user_id=' . $uid;
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
This page in the docs talks about this error in particular, but in the context of it being an app-only request resulting in an error, but this is not an app-only request, and the causes listed don't seem to apply.
Any ideas?
Found the answer. I was confusing two concepts. The oauth2/invalidate_token call is for bearer tokens in the case of application-only authentication, which now makes sense why the error is only documented for that case. I want to revoke a user token, which as I've come to learn, is not possible. So, the only way to manage this is to pretend to revoke the app on my side, and keep track of that. The app will still be auth'd in the user's Twitter account. For an example of this, try Pinterest. You can turn on Twitter through Pinterest and the Pinterest app will show in your Twitter account. If you turn off the app through Pinterest, and look again in your Twitter apps, it will still be there. In other words, you didn't turn it off. I'm leaving this here in case it helps someone else not waste time on this. It seems quite obvious we should be able to revoke an app (e.g Facebook allows this), but it seems you can't with Twitter. If anyone has more or different knowledge on this subject, please post it.

Twitter reverse authentication with PHP

I am trying to set up twitter reverse auth, on my api server. My mobile device will call this api endpoint to get the request token, and use that to sign-in using twitter, and do different actions on the hand-held device.
I am using j7mbo/twitter-api-php: Simplest PHP example for retrieving user_timeline with Twitter API version 1.1
This lib has just a basic post and get examples, but I looked into the source and found the buildOauth to doing everything that is required for twitter i.e. generate the signature base string and authorization header, and it calling the endpoint using curl.
In my code I set my consumer_key, secret, access_token key and secret, and set the x_auth_mode like below:
$tw_settings = array(
'consumer_key' => $app['config']['twitter_api']['consumer_key'][$culture],
'consumer_secret' => $app['config']['twitter_api']['consumer_secret'][$culture],
'oauth_access_token' => $app['config']['twitter_api']['api_access_token'][$culture],
'oauth_access_token_secret' => $app['config']['twitter_api']['api_access_token_secret'][$culture],
);
$postfields = array(
'x_auth_mode' => 'reverse_auth'
);
$twitter = new TwitterAPIExchange($tw_settings);
$result = $twitter->setPostFields($postfields)
->buildOauth($url, $requestMethod)
->performRequest();
return $app->json($result);
But twitter does not authenticate, saying "Failed to authenticate oauth signature and token".
I finally got it working. You can get this git repo based on j7mbo/twitter-php-api. I have extended to add a method to get reverse auth token from twitter. This token you can generate on your server, and expose it using an rest endpoint, which your device will call, and use it to do reverse authentication. This way the consumer-key and consumer secret is safe tucked away on the server and is not distributed with all the client devices.
Git repo: https://github.com/srinivasmangipudi/twitter-api-php
To generate the special request token, instantiate the TwitterApiExcahange object and then call 'buildReverseOauth' method. E.g:
$postfields = array(
'x_auth_mode' => 'reverse_auth'
);
$twitter = new TwitterAPIExchange($tw_settings);
$result = $twitter->setPostfields($postfields)
->buildReverseOauth($url, $requestMethod)
->performRequest();
This should return you the oauth_access_token. Rest everything is same as below.

Provider/Client 2-Legged OAuth I am understanding this correctly? (PHP implementation example)

I provide a developer API to a set of data, I want to add 2-legged oauth authentication so I can authenticate developers apps to use the api. Firstly is this the best solution, for this type of authentication?
Secondly, from an implementation/flow point of view, is my understanding correct:
A random developer, goes to my site and uses a 'signup' page, which when submitted I generate them a api key and secret, that can be generated in anyway I wish.
They then use an oauth library like the php one found here to sign their request with these credentials.
$consumer = new OAuthConsumer('thegeneratedkey', 'thegeneratedsecret');
$sig_method = new OAuthSignatureMethod_HMAC_SHA1;
//use oauth lib to sign request
$req = OAuthRequest::from_consumer_and_token($consumer, null, "GET", 'http://mydonaim/api/', array('someapimethod', 'somevalue'));
$sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$req->sign_request($sig_method, $consumer, null);//note: double entry of token
My server then uses the oauth library to check the 'signature' of that request to authenticate the developer app.
$secret = 'secret'; // Ignore this line.
$secret = 'secret'; // Use the $_GET['oauth_consumer_key'] to find the secret in my system.
$consumer = new OAuthConsumer($_GET['oauth_consumer_key'], $secret);
$sig_method = new OAuthSignatureMethod_HMAC_SHA1;
$method = $_SERVER['REQUEST_METHOD'];
$uri = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$sig = $_GET['oauth_signature'];
$req = new OAuthRequest($method, $uri);
//token is null because we're doing 2-leg
$valid = $sig_method->check_signature( $req, $consumer, null, $sig );
Is this correct?
If so, does this authentication have to be done every time a request is made or can I generate a token of some kind to reduce the weight in each HTTP request from developer app to my api?
Firstly is this the best solution, for this type of authentication?
OAuth is designed to allow applications to get user data from a third party service without knowing the user's credentials. As long as that's what you need to do, then OAuth is the right solution for you.
If so, does this authentication have to be done every time a request is made or can I generate a token of some kind to reduce the weight in each HTTP request from developer app to my api?
Both sets of Tokens/Secrets must be provided with every single API request and passed into your OAuth library for authentication. This is how OAuth works. You should not add yet another token into the process, as that would only make things even more complicated, and it would confuse the crap out of any poor developer that finally got OAuth.
Remember, the key sets exist so you can revoke access to an entire application, and so users can do the same, assuming you give them an interface to do so. Both sets are included with each request so your application can check them for validity.
Don't worry about the "weight" of an HTTP request unless you've performed benchmarking and profiling and have determined that the size of requests is something you need to work on. I can pretty much guarantee that it's a non-issue.

Categories