What I have:
Twitter app created at twitter and PHP app at localhost
What I want:
post tweets/update statuses via twitter API from only(!) the app account.
No twitter#anywhere, no user login, nothing fancy.
What I tried:
https://github.com/abraham/twitteroauth with access tokens from the dev.twitter.com website, returned
"POST data is not available with this
token"
or something like that.
code snippet I found on some website:
// Define credentials for the Twitter account
define('TWITTER_CREDENTIALS', 'username:password');
// Set up CURL with the Twitter URL and some options
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://twitter.com/statuses/update.xml?status=test_status');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Twitter uses HTTP authentication, so tell CURL to send our Twitter account details
curl_setopt($ch, CURLOPT_USERPWD, TWITTER_CREDENTIALS);
// Execute the curl process and then close
$data = curl_exec($ch);
curl_close($ch);
// If nothing went wrong, we should now have some XML data
echo '<pre>'.htmlentities(print_r($data, true)).'</pre>';
returned
"Basic authentication is not
supported"
That big code snippet uses basic authentication, which is no longer supported by Twitter. Disregard it.
OAuth is now required by Twitter instead, which is what abraham's twitteroauth library uses. You will have to log in/authenticate using this, at least once.
You will also have to first register your app with Twitter, to receive your own Consumer Key and Consumer Secret. Then you'll be able to start using Twitter's API via twitteroauth.
Okay I've found what's the problem.
By default, Twitter sets all apps to read-only, so even when you login via PHP, you can't send POST/UPDATE. What you need to do is go to your application settings (the one where you set app name, description and avatar) and before avatar there's a "default access type", switch it to
Read, Write, & Direct Messages
and voila.
to test the app use this snippet
$twitter = new \TwitterOAuth('consumer_key', 'consumer_secret',
'(oauth_token', 'oauth_token_secret');
$twitter->get('account/verify_credentials');
$twitter->post('statuses/update', array('status' => 'test status'));
Oh and you don't need to do the login stuff with your app, you get the required tokens under "My access Token" menu.
Related
I am learning to build a Login via Google button on my Joomla website, and I am following instruction on https://developers.google.com/identity/protocols/oauth2/web-server.
A little background:
I am using a third party extension to handle social login. Its facebook login works well, but its google login is outdated, still trying to connect to Google Plus endpoints. Clicking the login button on my page does lead to Google's account choice screen, after I choose an account and grant permission, there is a simple error message on the callback page. The author has stopped updating the extension, so for learning purpose, I've decided to fix it myself.
What I've achieved:
Currently I was able to get the access token from Google.
.......
$postdata = array(
'grant_type' =>'authorization_code',
'client_id' => $this->params->get('goappid'),
'client_secret' => $this->params->get('gosecret'),
'redirect_uri' => $this->getRedirectURL().'&task=gologin',
'code' => $_GET['code']);
curl_setopt($curl, CURLOPT_URL, 'https://oauth2.googleapis.com/token');
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postdata));
$oauth = json_decode(curl_exec($curl));
// Above code seems to be fine, getting $oauth response as follows
// "access_token": "token string",
// "expires_in": 3599,
// "scope": "https://www.googleapis.com/auth/userinfo.profile",
// "token_type": "Bearer",
// "id_token":"token string"
if (isset($oauth->access_token)) {
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_URL, 'https://www.googleapis.com/plus/v1/people/me?access_token='.$oauth->access_token); //Apparently outdated endpoint
$user = json_decode(curl_exec($curl));
if (empty($user->error)) {
curl_setopt($curl, CURLOPT_URL, 'https://www.googleapis.com/plus/v1/people/me/activities/public?access_token='.$oauth->access_token);//Apparently outdated endpoint
My question: At this point, I don't know what to do. The instruction says After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account, but how do I "make calls to a Google API"? To make a simple login via Google button, which API should I call? And to what endpoint should I make the request? I can't find this information from the instruction page. Above code is making request to https://www.googleapis.com/plus/v1/people/me?access_token, which is obviously outdated but how should I change this? This should have been provided by the instruction but I couldn't find it. And if I want to access other Google APIs, how do I "make calls" to them? a.k.a where do I find endpoints for each API?
I've also read https://developers.google.com/identity/protocols/oauth2/openid-connect, is what I am trying to do considered OIDC? Should I proceed according to this document?
I still think that access_token in the query path works in some Google apis. until June 2021
GET https://www.googleapis.com/plus/v1/people/me?access_token=[token]
I recommend switching to using an authorization header
GET https://people.googleapis.com/v1/%5BRESOURCENAME%5D HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
I am using Firebase Auth Rest API. I have code written in PHP to add the user to the database and firebase authentication. The information I store is kind, idToken, email, refreshToken, expiresIn, localId. It all works great!
Now when I am trying to delete the user from database it works fine but does not delete the user from the firebase authentication. Please find the code below for sign up and deleting the user.
The errors I get is either
CREDENTIALS_TOO_OLD_LOGIN_AGAIN (or)
INVALID_ID_TOKEN.
FIREBASE_KEY is my firebase key and in the $data I am passing the user idToken
/*
* User Sign Up
*/
function user_signup($data){
$response = true;
$data = json_encode($data);
$url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=".FIREBASE_KEY;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$jsonResponse = curl_exec($ch);
if(curl_errno($ch))
{
$response = false;
}
curl_close($ch);
return $jsonResponse;
}
/*
* User Delete
*/
/* function user_delete($data){
$response = true;
$data = json_encode($data);
$url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/deleteAccount?key=".FIREBASE_KEY;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$jsonResponse = curl_exec($ch);
if(curl_errno($ch))
{
$response = false;
}
curl_close($ch);
return $jsonResponse;
} */
There are two ways to interact with the Firebase REST APIs:
By authenticating your requests with a user's ID token, with the same permissions and limitations as if they would interact with your application on their own
By authenticating with the credentials of a Service Account, which gives you full access to your application, without any limitations.
To delete a user, you can use both methods, but when using a user's ID token, you have to authenticate as the user (effectively impersonating them) before being able to perform any actions on behalf of said user.
The better solution would be to use an Admin SDK to perform that task. By authenticating your requests to the Firebase REST APIs with Service Account Credentials as described in
Add the Firebase Admin SDK to Your Server, you will be able to perform administrative tasks (like deleting a user from the authentication database) more easily.
Here are the steps to get started with Service Account based authentication:
Generate Service Account credentials on https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk
Use the Google Auth Library for PHP to be able to make authenticated calls the Google/Firebase APIs https://github.com/googleapis/google-auth-library-php#call-the-apis
When you have created an HTTP client with the help of the Auth library, you can call this API endpoint to delete the user
$client->post('https://www.googleapis.com/identitytoolkit/v3/relyingparty/deleteAccount', [
'json' => [
'localId' => 'uid-of-user-to-delete'
]
]);
The localId parameter is not documented on https://firebase.google.com/docs/reference/rest/auth/#section-delete-account, but it's used from within the official admin SDK and works.
Using an Admin SDK (https://firebase.google.com/docs/admin/setup#initialize_the_sdk) would be the recommended way to perform administrative tasks like this. Official SDKs exist for Node.js, Java, Python, Go and C# - I maintain an unofficial one for PHP that you can find at https://github.com/kreait/firebase-php. With it, you could perform the same task like this:
// kreait/firebase-php ^5.0
$factory = (new Factory)->withServiceAccount('service_account.json');
$auth = $factory->createAuth();
$auth->deleteUser('uid-of-user-to-delete');
// kreait/firebase-php ^4.0
$serviceAccount = ServiceAccount::fromJsonFile('service_account.json');
$firebase = (new Factory())
->withServiceAccount($serviceAccount)
->create();
$firebase->getAuth()->deleteUser('uid-of-user-to-delete');
On a side note:
I would consider storing a user's ID token in a separate database a security risk: if your database gets compromised, attackers gain access to your user's ID tokens and can use those who aren't expired yet to access your application.
The recommended flow to pass a user from your frontend (web, mobile) to your backend (server) is:
Use a Firebase Client SDK in your frontend, e.g. in your web application
Let the user sign in to Firebase in the frontend via the client SDK, and when a user successfully signed in, retrieve the ID token on your client, send it to your backend and verify the ID token on your backend.
Once you've verified the ID token, you can extract the Firebase ID of your user from the ID token and save it to your database, e.g. in a table that maps your local user id to the Firebase User ID without the need to store their full ID token (= full credentials)
I'm pretty new to Basic HTTP Authentication (PHP) and would like to know how I can authenticate myself on the api of another website. I have a username and password to get access to the external api. Username is in $this->id, password is in $this->key.
This is the api url to get the data I want:
http://api.medipim.be/v2/web/product/print/0011890?language=nl&user_id='.$this->id.'&validation='.$this->key
How do I authenticate myself? Any options via curl?
Otto's answer is generally the right way to do authentication for the medipim api using php & curl. However, the api call in question does not require http authentication; the request is authenticated using a token based on your credentials. This way the url can be passed to a (web)client without exposing your api key. We've recently updated the documentation for this call, so you might want to have another look.
Yes, CURL can set the user and pass for you:
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
Replace $username with $this->id and similar with password
Previously I have been able to access the Facebook OAuth services through cURL in PHP. However, I am now getting a 2500 error (In this case An active access token must be used to query information about the current user.). I can access the information by using the URL straight through my web browser, however when I try to access it with cURL in PHP it doesnt work. I am using Facebook API v1.0, and the token is being generated with the Graph API Explorer.
What I have tried
I have tried creating a new access token, as well as tried using Facebook API v2.0 and the unversioned API. As I said above, I have tried using the exact same URLs in my browser, which works. I have also tried clearing cookies and trying again, as well as trying a whole different browser.
I have seen some of the other questions on SO which relate to this question but none of the answers work for me.
The code
The URL I am using is simply a call to the /me/home edge.
https://graph.facebook.com/v1.0/me/home/?since=1402913078&until=1402913213&access_token=<access token here>
Where <access token here> is the access token
The PHP cURL code looks like the following:
$url = "<the url here>";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
// get the response here...
It turns out that the actual URL being requested by cURL was different to the one that should have been being requested (the GET parameters were missing). This was caused by another location in the code.
To verify that the URL that is being requested is the same as the one passed to cURL, use the following code:
$requested_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
My site uses a php function to tweet an update whenever an event occurs. Right now I'm using the classic login technique, so the username and password for the associated Twitter account are just hard-coded in. The function looks like this:
function sendTweet($msg)
{
$username = 'username';
$password = 'password';
$url = 'http://twitter.com/statuses/update.xml';
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, "$url");
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_POST, 1);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, "status=$msg");
curl_setopt($curl_handle, CURLOPT_USERPWD, "$username:$password");
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);
}
I'd like to rewrite it to use OAuth, mostly to avoid problems down the road when classic login is deprecated, but also so that it will use the name of my application instead of "from API" after every tweet.
All the examples I can find involve creating an authentication system, which sends the user to twitter.com to approve the authentication request, then sends them back to the originating site with an appropriate token. For my application though there's only one twitter account and it doesn't belong to the user who initiates the action (who may not even know or care that he is initiating a tweet).
So how do I do this? The best option I can think of is to build a one-time-use script which will let me request an access token, then hard code that token into the sendTweet function. That seems like a lot of overkill for such a simple application, and it creates a potential problem down the road if Twitter ever expires the access token. The docs say they probably never will, but that applications should be designed to handle it gracefully if they do.
Does anyone have experience with a project like this? Is there a simpler and more graceful way to do it?
Using abraham PHP Twitter OAuth Library and use single access token.
You should write the OAuth script into your admin panel (assuming you've got one). If your access-key expires, you can just re-authorize from your admin.
If you need an example, I wrote a single use token bot with complete instructions using Abrahams OAuth.
http://www.edwardhotchkiss.com/blog/twitter-bot-using-oauth/