In my application i want to use the Soundcloud API with my own Soundcloud user. The Soundcloud API authentication process involves a user being redirected to the Soundcloud homepage, login and authorize the application, so that the page can use the API for this user.
I want to automate the whole process, because my own user is the only user which gets authenticated. Is that possible?
Here is my code so far:
$soundcloud = new \Services_Soundcloud(
'**',
'**',
'http://**'
);
$authorizeUrl = $soundcloud->getAuthorizeUrl();
$accessToken = $soundcloud->accessToken();
try {
$me = json_decode($soundcloud->get('me'), true);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
But the line $accessToken = $soundcloud->accessToken(); throws an exception:
The requested URL responded with HTTP code 401.
500 Internal Server Error - Services_Soundcloud_Invalid_Http_Response_Code_Exception
Hi All,
Here I am going to share my experience with Soundcloud API (PHP)
See my Question: Link
Recently I started to work with Sound cloud API (PHP) and I decided to use PHP API by
https://github.com/mptre/php-soundcloud.
But When I was trying to get access token from Sound cloud server by this code:
// Get access token
try {
$accessToken = $soundcloud->accessToken($_GET['code']);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
I had check the $_GET['code'] value. But strange there is nothing in
$_GET['code'] this is blank. The Soundcloud was returning "The
requested URL responded with HTTP code 0" error. That time I was
testing Soundcloud on WAMP Localhost.
Allot of Goggling I found a solution to fix "The requested URL
responded with HTTP code 0" issue. I had download 'cacert.pem' file
and put inside our demo project folder (inside Services/Soundcloud/).
Then after I added some code in 'class Services_Soundcloud'
function protected function _request($url, $curlOptions = array()).
// My code in side function
$curlPath = realpath(getcwd().'\Services\cacert.pem');
$curlSSLSertificate = str_replace("\\", DIRECTORY_SEPARATOR, $curlPath);
curl_setopt($ch, CURLOPT_CAINFO, $curlSSLSertificate);
Saved 'class Services_Soundcloud' file and moved on live server. After
move my project from WAMP to Live server I start to check it again.
When I open my index.php it's ask me to login
I use my Facebook account to login.
after login it was asking to connect with Soundcloud
after connect everything working smooth, I got my info with
$me = json_decode($soundcloud->get('me'));
but a new problem start to occurring which was that my access token
being expire again and again. Then I use session :D
// code for access token
$code = $_GET['code'];
// Get access token
try {
if(!isset($_SESSION['token'])){
$accessToken = $soundcloud->accessToken($code);
$_SESSION['token'] = $accessToken['access_token'];
}else{
$soundcloud->setAccessToken($_SESSION['token']);
}
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
And now everything working awesome. i can get all my details, tracks everything from SC server
Hope it will help you to fight with Soundcloud API Cheers!!!! :)
I'm looking for the same thing, but according to the soundcloud's api (check the Authenticating without the SoundCloud Connect Screen paragraph):
// this example is not supported by the PHP SDK
..and is not supported by the Javascript neither.
I've tryed to auth with python:
# create client object with app and user credentials
client = soundcloud.Client(client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
username='YOUR_USERNAME',
password='YOUR_PASSWORD')
..then the uploading python method:
# upload audio file
track = client.post('/tracks', track={
'title': 'This is my sound',
'asset_data': open('file.mp3', 'rb')
})
and it works just fine.
So, for now, you have 2 ways:
Use another language, Python or Ruby (the only 2 sdk that actually support this feature) or use a small python/ruby script as a bridge for this particular need;
Add this funcionaliy to the PHP SDK (i'm trying to do it quick'n'dirty, if i get success, i'll share ;)
There is no magic behind its implementation in Python and Ruby SDK's.
What's happening is that POST request is sent to http://api.soundcloud.com/oauth2/token with the following params:
client_id='YOUR_CLIENT_ID'
client_secret='YOUR_CLIENT_SECRET'
username='YOUR_USERNAME'
password='YOUR_PASSWORD'
And Content-Type: application/x-www-form-urlencoded
The response body contains access_token, that can be used for the further authorization of your requests. Thus, your GET request to /me endpoint will look like: /me?oauth_token=YOUR_ACCESS_TOKEN&client_id=YOUR_CLIENT_ID. (I believe, client_id is redundant here but all their apps keep adding it).
Here is the Postman Doc I created for demonstration: https://documenter.getpostman.com/view/3651572/soundcloud/7TT5oD9
Related
I am trying make a registration with FB option for my PHP based website. My callback url for the website is
http://subdomain.mydomain.com/user/fblogincb/
I have added that in the Valid OAuth redirect URIs in my Apps Facebook Login settings. The login button of my website correctly invoke the callback url, but when I try to use the access token in my call back page using the follwing code:
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
}
it return the exception:
Graph returned an error: Can't Load URL: The domain of this URL isn't included in the app's domains. To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings.
The redirected URL from FB is:
http://subdomain.mydomain.com/user/fblogincb/?code=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
However, turning off the Strict URLs mode does not have this issue. What am I doing wrong here for the Strict URLs mode. Any help will be appreciated.
Try and pass the exact redirect URL that was used in the login dialog call, as parameter to the getAccessToken method:
$accessToken = $helper->getAccessToken('http://subdomain.mydomain.com/user/fblogincb/');
The exact same redirect_uri parameter value must be passed in both calling the login dialog, and in the subsequent API call that exchanges the code for a token. The SDK has its own "URL detection handler" on board (or you can supply your own, in environments where custom routing logic might require that) for the purpose of determining the current URL - which usually does the job fine, but depending on the exact setup, it can fail sometimes.
I am a bit surprised by the error message, I remember seeing a different one in such cases that explicitly mentioned the redirect_uri mismatch ... but maybe while implementing strict mode something changed internally, dunno.
Do not forget to update Facebook PHP SDK to latest v5.6.2, strips code param from Facebook redirect_uri callback
Facebook SDK for PHP - changelog
5.6.2 (2018-02-15)
Strip 'code' param (#913)
I am testing the Gmail API.
So far I have done the following:
I have created the project in the Google Developers Console
I have enabled the Gmail API.
I have created a new Client ID and the client secret.
In my PHP script I have installed the PHP Client library and followed
the instructions for the setup in PHP.
So now when I run the file quickstart.php it gives a link. When I open it, it appears an authorization page where I authorize my application to access the Gmail API.
Then it redirects to the Redirect URIs that I have declared in the setup (adding the code parameter).
In the address bar it appears exactly this:
http://localhost/main/gmail_callback?code=MY_CODE
Where main is my controller and gmail_callback so far is just a blank function.
And it should be correct since these are my settings:
Javascript origins: http://localhost
Redirect URIs: http://localhost/main/gmail_callback
What do I do next?
The next step in the flow is to exchange the Authorization Code for an Access Token (which will also include a Refresh Token if you requested offline access). If you use the https://developers.google.com/oauthplayground/ to execute the flow manually, you'll be able to see the URLs involved. There is a php library call to do the same thing, but I personally prefer to send my own HTTP rather than use a library. Even if you do use a library, it will still be worth spending a little time to understand the HTTP flow so you can more easily debug any problems you encounter.
Basically I was approaching wrongly. Following these instructions is enough to get the tokens:
https://developers.google.com/gmail/api/quickstart/php
The main point is to access the file from the command line and not from the app.
I made a Oauth Gmail some months ago, I got something like this :
In my callback function :
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
return $this->redirect($auth_url);
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = Router::url('/', true).'Users/gmail';
return $this->redirect($redirect_uri);
}
And in my gmail() function :
public function gmail(){
require APPLIBS.'Google/src/Google'.DS.'autoload.php';
$client = new Google_Client();
$client->setAuthConfigFile('../Config/client_secrets.json');
$client->addScope(Google_Service_Oauth2::PLUS_LOGIN);
$client->addScope(Google_Service_Oauth2::USERINFO_EMAIL);
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$oauth_service = new Google_Service_Oauth2($client);
$data['Profile']['last_name'] = $oauth_service->userinfo->get()->familyName;
}
}
$data['Profile']['last_name'] contain the last_name of the user, for example.
I have a browser-based app (single page, AngularJS) and am using hello to use third party signin such as Google, FB, Soundcloud, etc.
My app uses a PHP API server.
What's a good way to have the user able to login using Google, but also verify the user on the server side?
I was considering:
The browser app performs an implicit grant with google/fb/etc
I then transfer the access_token from the client to the server, then use, for example, a google-api-php-client with my app id, secret and the user access_token? Using their API such as /me? (which grant type would this be?)
Retrieve some key from the third-party (facebook_id, email, etc), match it against a user in my database, and then consider the user authenticated?
Also, should I perform this on each API request? Or should I just stash the access_token for a bit and assume that the user is still valid until the key expires?
One issue is that not all of those providers support the implicit flow. But assuming they do, the access_token you get for each will be proof that the user authenticated with that system, not necessarily that they have access to call your API. You still need something that asserts that "someone#gmail.com can 'read' resource X in your system"
You probably need something that translates whatever you get from Google, Soundcloud, etc. into a token your app understands. A simple(r) format is to use JWT. (Json Web Tokens).
App -> Intermmediary -> Soundcloud/Google
<-JWT--+ <---whavetever-+
and then:
App - (JWT) -> API
JWT are easy to manipulate, validate and verify. See jwt.io
You might want to look at this blog post also for some additional information (specifically on AngularJS front-ends)
The blog post #eugenio-pace mentioned was really helpful for setting up the client side.
For the server side though, the access_token should be validated.
The SDK's are (in composer) (code below):
Facebook: "facebook/php-sdk-v4" : "4.0.*"
Google: cURL request (didn't care for "google/apiclient")
SoundCloud: "ise/php-soundcloud": "3.*"
(There are others of course, just these three were the ones I chose, and seem decent.)
Last time I did something like this I made the mistake of validating the access_token on every request, which had a huge (obviously negative) impact on performance. Now I just validate it on login and use it to retrieve the user's ID from that service. So, the browser sends me access_token A and says it's from Facebook, I use the sdk above the the access_token with Facebook, and I get back their ID so I know they are who they say they are.
I'd suggest storing the access_token on the server with the expires_in.
(I haven't dealt with refresh token's yet)
Code to validate tokens using the above libraries:
function validateTokenFacebook($token, $id=null) {
// Performed above
// FacebookSession::setDefaultApplication($config->fb->app_id, $config->fb->secret);
$session = new FacebookSession($token);
// Fetch user info
$request = new FacebookRequest($session, 'GET', '/me');
try {
$response = $request->execute();
} catch (\Facebook\FacebookServerException $e) {
$this->mlog->err($e . "\n" . $e->getTraceAsString());
throw new AuthTokenInvalidException();
}
$graphObject = $response->getGraphObject();
$user_id = $graphObject->getProperty('id');
return array(access_token, $user_id);
}
function validateTokenGoogle($token, $id=null) {
$resp=array();
// This key isn't included in the token from hello.js, but
// google needs it
if (!array_key_exists('created', $token)) $token['created'] = $token['expires'] - $token['expires_in'];
$client = new \Google_Client();
$client->setClientId($this->systemConfig->google->app_id);
$client->setClientSecret($this->systemConfig->google->secret);
$client->setRedirectUri($this->systemConfig->google->redirectUri);
$client->setScopes('email');
$client->setAccessToken(json_encode($token));
try {
// Send Client Request
$objOAuthService = new \Google_Service_Oauth2($client);
$userData = $objOAuthService->userinfo->get();
return array($token['access_token'], $userData['id']);
} catch (\Google_Auth_Exception $e) {
throw new AuthException('Google returned ' . get_class($e));
}
}
function validateTokenSoundcloud($token, $id=null) {
$soundcloud = new \Soundcloud\Service(
$this->systemConfig->soundcloud->app_id,
$this->systemConfig->soundcloud->secret,
$this->systemConfig->soundcloud->redirect);
$soundcloud->setAccessToken($access_token);
try {
$response = json_decode($soundcloud->get('me'), true);
if (array_key_exists('id', $response))
return array($access_token, $response['id']);
} catch (Soundcloud\Exception\InvalidHttpResponseCodeException $e) {
$this->mlog->err($e->getMessage());
}
throw new AuthTokenInvalidException();
}
I have a few custom classes above, such as the Exceptions and the systemConfig, but I think it's verbose enough to communicate what they do.
I'm trying to post notification using facebook graph api post method but I'm getting
(#15) This method must be called with an app access_token.
However the access_token which I'm sending in querystring is app access token which is fetched using this method
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".FB_APP_ID."&client_secret=".FB_SECRET."&grant_type=client_credentials";
I 've seen few guys have implemented it but don't know why its not working for me, someone pls tell me where I'm wrong in it.
Thanks
EDIT
I got it working, here is the change
This line of code will never work, because the internal access_token will override the app access_token which we are trying to pass in query string.
$this->facebook->api("/".$to_userId."/notifications?access_token=$app_token_url&template=message",'POST');
So Use this code
$data = array(
'href'=> 'https://apps.facebook.com/MY_APP/',
'access_token'=> $app_token,
'template'=> 'test'
);
try {
$this->facebook->api("/".$to_userId."/notifications",'POST',$data);
} catch (FacebookApiException $e) {
}
Is your app accidentally configured as a 'native/desktop' app in the app settings? if so, change it back to 'web'
Using Facebook's PHP SDK, I was able to get Facebook login working pretty quickly on my website. They simply set a $user variable that can be accessed very easily.
I've had no such luck trying to get Twitter's OAuth login working... quite frankly, their github material is confusing and useless for someone that's relatively new to PHP and web design, not to mention that many of the unofficial examples I've tried working through are just as confusing or are outdated.
I really need some help getting Twitter login working--I mean just a basic example where I click the login button, I authorize my app, and it redirects to a page where it displays the name of the logged in user.
I really appreciate your help.
EDIT I'm aware of the existence of abraham's twitter oauth but it provides close to no instructions whatsoever to get his stuff working.
this one is the basic example of getting the url for authorization and then fetching the user basic info when once u get back from twitter
<?php
session_start();
//add autoload note:do check your file paths in autoload.php
require "ret/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
//this code will run when returned from twiter after authentication
if(isset($_SESSION['oauth_token'])){
$oauth_token=$_SESSION['oauth_token'];unset($_SESSION['oauth_token']);
$consumer_key = 'your consumer key';
$consumer_secret = 'your secret key';
$connection = new TwitterOAuth($consumer_key, $consumer_secret);
//necessary to get access token other wise u will not have permision to get user info
$params=array("oauth_verifier" => $_GET['oauth_verifier'],"oauth_token"=>$_GET['oauth_token']);
$access_token = $connection->oauth("oauth/access_token", $params);
//now again create new instance using updated return oauth_token and oauth_token_secret because old one expired if u dont u this u will also get token expired error
$connection = new TwitterOAuth($consumer_key, $consumer_secret,
$access_token['oauth_token'],$access_token['oauth_token_secret']);
$content = $connection->get("account/verify_credentials");
print_r($content);
}
else{
// main startup code
$consumer_key = 'your consumer key';
$consumer_secret = 'your secret key';
//this code will return your valid url which u can use in iframe src to popup or can directly view the page as its happening in this example
$connection = new TwitterOAuth($consumer_key, $consumer_secret);
$temporary_credentials = $connection->oauth('oauth/request_token', array("oauth_callback" =>'http://dev.crm.alifca.com/twitter/index.php'));
$_SESSION['oauth_token']=$temporary_credentials['oauth_token']; $_SESSION['oauth_token_secret']=$temporary_credentials['oauth_token_secret'];$url = $connection->url("oauth/authorize", array("oauth_token" => $temporary_credentials['oauth_token']));
// REDIRECTING TO THE URL
header('Location: ' . $url);
}
?>
I just tried abraham's twitteroauth from github and it seems to work fine for me. This is what I did
git clone https://github.com/abraham/twitteroauth.git
Upload this into your webhost with domain, say, www.example.com
Go to Twitter Apps and register your application. The changes that you need are (assuming that you will use abraham's twitteroauth example hosted at http://www.example.com/twitteroauth)
a) Application Website will be http://www.example.com/twitteroauth
b) Application type will be browser
c) Callback url is http://www.example.com/twitteroauth/callback.php (Callback.php is included in the git source)
Once you do this, you will get the CONSUMER_KEY and CONSUMER_SECRET which you can update in the config.php from the twitteroauth distribution. Also set the callback to be the same as http://www.example.com/twitteroauth/callback.php
Thats it. If you now navigate to http://www.example.com/twitteroauth, you will get a "Signin with Twitter", that will take you to Twitter , authorize the request and get you back to the index.php page.
EDIT:
Example will not work but do not worry. Follow the above steps and upload to server.
Make sure you rename the file from github repository i.e. config-sample.php->config.php
if you want to see a working sample, find it here
Here are some OAuth 1.0A PHP libraries with examples:
tmhOAuth
Oauth-php
Twitter async
Twitter async provides documentation on how to simply sign in a user as you asked for.
Here is the step by step guide to integrate Twitter OAuth API to Web-application using PHP. Please following tutorial.
http://www.smarttutorials.net/sign-in-with-twitter-oauth-api-using-php/
You need to create Twitter App First By going thorugh following URL
https://apps.twitter.com/
Then you need to provide necessary information for the twitter app. Once your provided all the information and then save it. You will get Twitter application Consumer Key and Consumer secret.
Please download the source file from above link, and just replace TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET and TWITTER_OAUTH_CALLBACK with your Consumer Key (API Key), Consumer Secret (API Secret) and callback URL. Then upload this to your server. Now it will work successfully.
Abraham's Twitteroauth has a working demo here:
https://github.com/abraham/twitteroauth-demo
Following the steps in the demo readme worked for me. In order to run composer on macOS I had to do this after installing it: mv composer.phar /usr/local/bin/composer
IMO the demo could be a lot simpler and should be included in the main twitteroauth repo.
I recently had to post new tweets to Twitter via PHP using V2 of their API but couldn’t find any decent examples online that didn’t use V1 or V1.1. I eventually figured it out using the great package TwitterOAuth.
Install this package via composer require abraham/twitteroauth first (or manually) and visit developer.twitter.com, create a new app to get the credentials needed to use the API (see below). Then you can post a tweet based on the code below.
use Abraham\TwitterOAuth\TwitterOAuth;
// Connect
$connection = new TwitterOAuth($twitterConsumerKey, // Your API key
$twitterConsumerSecret, // Your API secret key
$twitterOauthAccessToken, // From your app created at https://developer.twitter.com/
$twitterOauthAccessTokenSecret); // From your app created at https://developer.twitter.com/
// Set API version to 2
$connection->setApiVersion('2');
// POST the tweet; the third parameter must be set to true so it is sent as JSON
// See https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets for all options
$response = $connection->post('tweets', ['text' => 'Hello Twitter'], true);
if (isset($response['title']) && $response['title'] == 'Unauthorized') {
// Handle error
} else {
var_dump($response);
/*
object(stdClass)#404 (1) {
["data"]=>
object(stdClass)#397 (2) {
["id"]=>
string(19) "0123456789012345678"
["text"]=>
string(13) "Hello Twitter"
}
}
*/
}