I'm using this composer package https://github.com/basvandorst/StravaPHP
The OAUTH is working fine and its generating me the JSON with the access token and user id, etc..
But whenever I try to use other function it returns me 404 not found.
Output is this :
{"token_type":"Bearer","access_token":"077058e0c800881c72a4b10a04a520d5898d4e3e","athlete":{"id":35670467,"username":"amir_do","resource_state":2,"firstname":"Amir","lastname":"Do","city":null,"state":null,"country":null,"sex":"M","premium":false,"summit":false,"created_at":"2018-10-13T13:55:41Z","updated_at":"2018-10-13T13:56:25Z","badge_type_id":0,"profile_medium":"https://lh5.googleusercontent.com/-ku6v9lKNgYY/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbASj8KhClhwnVYVqRrEG2oiYzWPbA/mo/photo.jpg","profile":"https://lh5.googleusercontent.com/-ku6v9lKNgYY/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbASj8KhClhwnVYVqRrEG2oiYzWPbA/mo/photo.jpg","friend":null,"follower":null,"email":"goncalomaia97#gmail.com"}}
35670467
Client error: `GET https://www.strava.com/api/athletes/35670467/stats?access_token=077058e0c800881c72a4b10a04a520d5898d4e3e` resulted in a `404 Not Found` response: {"message":"Record Not Found","errors":[{"resource":"resource","field":"path","code":"invalid"}]}
And this is my current callback.php page code:
<?php
include 'vendor/autoload.php';
use Strava\API\Client;
use Strava\API\Exception;
use Strava\API\Service\REST;
session_start();
$client = new GuzzleHttp\Client();
global $connect;
require_once("configs/database.php");
$connect = new mysqli($config['database']['host'],$config['database']['user'],$config['database']['pass'],$config['database']['db']);
$code = $_GET['code'];
$state = $_GET['state'];
$scope = $_GET['scope'];
$user = $_SESSION['username'];
$check = $connect->query("SELECT * FROM users WHERE email = '$user'");
$fetch = $check->fetch_array(MYSQLI_ASSOC);
$apix = $fetch['api'];
$api_secretx = $fetch['api_secret'];
$client = new GuzzleHttp\Client();
$data = [
"client_id" => $apix,
"client_secret" => $api_secretx,
"code" => $code
];
$result = $client->post('https://www.strava.com/oauth/token', ['json' => $data]);
print "<pre>";
print_r( $result->getBody()->getContents() );
print "</pre>";
$bodyb = $result->getBody();
$varx = json_decode((string) $bodyb, true);
$token = $varx['access_token'];
$id = $varx['athlete']['id'];
$_SESSION['token'] = $token;
printf($id);
try {
// REST adapter (We use `Guzzle` in this project)
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3']);
// Service to use (Service\Stub is also available for test purposes)
$service = new \Strava\API\Service\REST($token, $adapter);
// Receive the athlete!
$client = new Client($service);
$athlete = $client->getAthleteStats($id);
print_r($athlete);
} catch(Exception $e) {
print $e->getMessage();
}
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3']);
Change that to this (It should be trailing) :
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3/']);
Related
I spent some time without touching this Api, and now I have received the following error:
Unpermitted fields present in REQUEST_BODY:
It's a sharing code:
$link = 'https://example.com.br';
$access_token = $access_token;
$linkedin_id = $linkedin_profile_id;
$body = new \stdClass();
$body->content = new \stdClass();
$body->content->contentEntities[0] = new \stdClass();
$body->text = new \stdClass();
$body->content->contentEntities[0]->thumbnails[0] = new \stdClass();
$body->content->contentEntities[0]->entityLocation = $link;
$body->content->contentEntities[0]->thumbnails[0]->resolvedUrl = "https://example.com.br/img/logo-header-120x50.png";
$body->content->title = 'Example';
$body->owner = 'urn:li:person:'.$linkedin_id;
$body->text->text = 'Kasum';
$body->visibility = new \stdClass();
$body->visibility->code = new \stdClass();
$body->visibility->code = 'anyone';//<-------------that is a line error
$body_json = json_encode($body, true);
try {
$client = new Client(['base_uri' => 'https://api.linkedin.com']);
$response = $client->request('POST', '/v2/shares', [
'headers' => [
"Authorization" => "Bearer " . $access_token,
"Content-Type" => "application/json",
"x-li-format" => "json"
],
'body' => $body_json,
]);
if ($response->getStatusCode() !== 201) {
echo 'Error: '. $response->getLastBody()->errors[0]->message;
}
echo 'Post is shared on LinkedIn successfully';
} catch(Exception $e) {
echo $e->getMessage(). ' for link '. $link;
}
As indicated in the code, the visibility field triggers this error
Without it, sharing occurs, but with visibility only for connections. That way the post loses the share button.
Is it no longer allowed to configure this field, or am I doing it wrong?
How to send a correct authorization header for basic authentication using guzzle
use GuzzleHttp\Client;
$username='EFDEMO';
$password='EFDEMO';
$client = new Client(['auth' => [$username, $password]]);
$res = $client->request('GET', 'https://mb-
rewards.calusastorefront.p2motivate.com/client/json.php/
getMemberAccount');
$res->getStatusCode();
$response = $res->getBody();
echo $response;
the error I am getting
{"statusCode":"Error","error":
{"errorCode":"400","errorMessage":"Authentication Header ID field must
match Basic Authentication Username"}}
Referring to documentation you should pass the auth parameter in request method instead of client's constructor:
$client = new Client();
$res = $client->request(
'GET',
'past-url-here',
['auth' => [$username, $password]]
);
I solved it like below
<?php
require '../x_static_libs/guzzle/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
$username = 'xxxxxx';
$password = 'xxxxxxxx';
$token = 'xxxxxxxxxxxxxxxxxxxx';
$url = 'https://ervb-rewards.com/client/json.php';
$api_token =
base64_encode(json_encode(['id'=>'xxxxxxx','token'=>'xxxxxxxxxxxxxxxxxxxxxx']));
$res = $client->request(
'GET',
$url.'/getMemberAccount',
['auth' => [$username,$api_token]]
);
$jsonData = json_decode($res->getBody(), true);
echo "<pre>";
print_r($jsonData);
echo "</pre>";
I am working in building a restful api using php & slim for my app backend and also we have a web version but my team use pure php with the web suit , we work separately . it is just the first time that i have the backend responsibility I have a miss understanding about how i can handle the authentication in a secure and professional way i have read this article but i need a detailed way how to implement it in php & slim and extend it to the web team so to use the same authentication technic .
this is how the log in / sign up code that i have used :
help me to improve it :
$app->post('/api/create_user', function( $request , $response , $args ){
require('../config.php');
$email = $_POST['email'];
$qry= "select * from user where email ='". $email."'";
$result=$mysqli->query($qry);
if(mysqli_num_rows($result)>0){
$user = new stdClass();
$user->status=0;
$user->error=" the email is registered ";
$result = new stdClass();
$result->result=$user;
}
else {
$password = md5($_POST['password']);
$image=$_FILES['image']['name'];
$email=$_POST['email'] ;
$nickname =$_POST['nickname'];
$birthDay=$_POST['birthdate'];
$insert_req="INSERT INTO user VALUES ('', '$email', '$password','$nickname')";
$insert_user_result=$mysqli->query($insert_req);
if ($insert_user_result) {
$user = new stdClass();
$user->status=1;
$result = new stdClass();
$result->result=$user;}
else {$user = new stdClass();
$user->status=2;
$user->error=mysql_error();
$result = new stdClass();
$result->result=$user;}
}
if (isset($result)){
header('Content-type: application/json');
echo json_encode($result);}
});
?>
<?php
$app->post('/api/login', function( $request , $response , $args ){
require('../config.php');
$email =$_POST['email'];
$password = md5($_POST['password']);
$findemail_qry= "select user_id from user where email ='". $email."'";
$findemail_result =$mysqli->query($findemail_qry);
if(mysqli_num_rows($findemail_result)>0)
{
$login_qry="select user_id from user where email ='". $email."'AND password ='".$password."'";
$login_result =$mysqli->query($login_qry);
if(mysqli_num_rows($login_result)>0)
{
$data =mysqli_fetch_assoc ($login_result);
$user_id=$data['user_id'];
$user = new stdClass();
$user->status=1;
$user->user_id=$user_id;
$result = new stdClass();
$result->result=$user;}
else
{$user = new stdClass();
$user->status=2;
$user->error="wrong password";
$result = new stdClass();
$result->result=$user; }
}
else
{$user = new stdClass();
$user->status=0;
$user->error=" this email not registered ";
$result = new stdClass();
$result->result=$user;}
if (isset($result)){
header('Content-type: application/json');
echo json_encode($result);
}
});
?>
You can use JWT in your slim application as your authntication layer for Your API
You can use this library to implement it
Slim JWT
In a simple way you can use something like this
Try to use Basic authorization to send user name and password
Then You will generate a new JWT Token ,That will used in all others API
<?php
use \Firebase\JWT\JWT;
use \Slim\Middleware\HttpBasicAuthentication\AuthenticatorInterface;
require '../vendor/autoload.php';
$app = new \Slim\App;
class RandomAuthenticator implements AuthenticatorInterface {
public function __invoke(array $arguments) {
//validation for user and password
$Password=$arguments['password'];
$user=$arguments['user'];
if(($Password=="admin") &&($user=="admin") ){
return true;
}
else{
return false ;
}
}}
//add http basic middleware for login route
$app->add(new \Slim\Middleware\HttpBasicAuthentication([
"path" => "/login",
"realm" => "Protected",
"authenticator" => new RandomAuthenticator()
]));
$app->post("/login", function ($request, $response, $arguments) {
//generate JWT token
$now = new DateTime();
$future = new DateTime("now +20 minutes");
$server = $request->getServerParams();
$payload = [
"iat" => $now->getTimeStamp(),
"exp" => $future->getTimeStamp(),
"sub" => $server["PHP_AUTH_USER"],
];
$secret = "TOURSECERTKEY";
$token = JWT::encode($payload, $secret, "HS512");
$data["status"] = "ok";
$data["token"] = $token;
return $response->withStatus(201)
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
});
//Add jWT token Authorization middleware for all API
$app->add(new \Slim\Middleware\JwtAuthentication([
"path" => ["/"],
"passthrough" => ["/login"],
"secret" => "TOURSECERTKEY",
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
]));
I successfully setup twitteroauth and posted a message. Now, when I try to post again, and every time AFTER THE FIRST successful message post, I get an error Your credentials do not allow access to this resource. (code 220);
Here's my code:';
$message = 'Test';
$apiKey = Ranger_Application_Util::getConfig('twitter_app_api_key');
$apiSecret = Ranger_Application_Util::getConfig('twitter_app_api_secret');
$consumerToken = Ranger_Application_Util::getStorageData('twitter_oauth_token');
$consumerSecret = Ranger_Application_Util::getStorageData('twitter_oauth_secret');
$twitterOauthVerifier = Ranger_Application_Util::getStorageData('twitter_oauth_verifier');
$_SESSIOM['oauth_token'] = $consumerToken;
$_SESSION['oauth_token_secret'] = $consumerSecret;
require_once 'twitter/twitteroauth.php';
$connection = new TwitterOAuth($apiKey,$apiSecret,$consumerToken,$consumerSecret);
$connection->host = "https://api.twitter.com/1.1/";
$accessToken = $connection->getAccessToken($twitterOauthVerifier);
$_SESSION['access_token'] = $accessToken;
$parameters = array('status' => $message);
$status = $connection->post('statuses/update',$parameters);
Core::dump($status);
die();
The data I retrieve from getStorageData is values stored in the database that pertain to that specific user.
Unless you are storing the information from $accessToken to your database in a piece of code you have not posted, I believe the issue may be that you are getting the access token after your initial connection, but not using the permanent access information from the access token when trying to post to the connection. So any future requests will not be using the permanent credentials and are therefore rejected. Try something like this:
$message = 'Test';
$apiKey = Ranger_Application_Util::getConfig('twitter_app_api_key');
$apiSecret = Ranger_Application_Util::getConfig('twitter_app_api_secret');
$twitterOauthVerifier = Ranger_Application_Util::getStorageData('twitter_oauth_verifier');
require_once 'twitter/twitteroauth.php';
$hasAccessToken = (
array_key_exists('oauth_token', $_SESSION) &&
array_key_exists('oauth_token_secret', $_SESSION));
if ($hasAccessToken)
{
$consumerToken = $_SESSION['oauth_token'];
$consumerSecret = $_SESSION['oauth_token_secret'];
}
else
{
$consumerToken = Ranger_Application_Util::getStorageData('twitter_oauth_token');
$consumerSecret = Ranger_Application_Util::getStorageData('twitter_oauth_secret');
$connection = new TwitterOAuth($apiKey, $apiSecret, $consumerToken, $consumerSecret);
$connection->host = "https://api.twitter.com/1.1/";
$accessToken = $connection->getAccessToken($twitterOauthVerifier);
$consumerToken = $accessToken['oauth_token'];
$consumerSecret = $accessToken['oauth_token_secret'];
$_SESSION['oauth_token'] = $consumerToken;
$_SESSION['oauth_token_secret'] = $consumerSecret;
}
$connection = new TwitterOAuth($apiKey, $apiSecret, $consumerToken, $consumerSecret);
$connection->host = "https://api.twitter.com/1.1/";
$parameters = array('status' => $message);
$status = $connection->post('statuses/update', $parameters);
Core::dump($status);
die();
You may want to store the oauth token information in your database after receiving it from getAccessToken() rather than using sessions. Maybe you have a method like Ranger_Application_Util::setStorageData('twitter_oauth_token', $consumerToken)?
This
$_SESSIOM['oauth_token'] = $consumerToken;
^
should be
$_SESSION['oauth_token'] = $consumerToken;
How do I use this function?
I have a userid and a group id.
The error message I get when I try to add my fields has to do with the Google_Member instance. How would I use this in my PHP code?
BTW it is from the Google Apps API
/**
* Add user to the specified group. (members.insert)
*
* #param string $groupKey Email or immutable Id of the group
* #param Google_Member $postBody
* #param array $optParams Optional parameters.
* #return Google_Member
*/
public function insert($groupKey, Google_Member $postBody, $optParams = array()) {
$params = array('groupKey' => $groupKey, 'postBody' => $postBody);
$params = array_merge($params, $optParams);
$data = $this->__call('insert', array($params));
if ($this->useObjects()) {
return new Google_Member($data);
} else {
return $data;
}
}
Follow the instructions listed here to setup the application in Google Console and to enable Domain Delegation of Authority.
http://jamespeckham.com/wordpress/?p=9 (Thank you JDPeckham)
Download the client from: https://code.google.com/p/google-api-php-client/downloads/list
Here is my working code:
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DirectoryService.php";
require_once "google-api-php-client/src/contrib/Google_Oauth2Service.php";
session_start();
const GROUP_SCOPE = 'https://www.googleapis.com/auth/admin.directory.group';
const SERVICE_ACCOUNT_EMAIL = '.....#developer.gserviceaccount.com';
const SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/to/...privatekey.p12';
const CLIENT_ID = '....apps.googleusercontent.com';
$userEmail = 'email-address-with-admin-rights#domain.com';
$key = file_get_contents(SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(SERVICE_ACCOUNT_EMAIL, array(GROUP_SCOPE), $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', $userEmail);
$client = new Google_Client();
$client->setClientId(CLIENT_ID); // from API console
$client->setApplicationName("Project Name from API Console");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
$member = new Google_Member(array('email' => 'abc#testing.com',
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER'));
$service = new Google_DirectoryService($client);
$results = $service->members->insert('mailing-list-name#domain.com', $member);
print '<h2>Response Result:</h2><pre>' . print_r($results, true) . '</pre>';
require_once $_SERVER['DOCUMENT_ROOT'] . '/../vendor/autoload.php';
$updateName = $_POST["name"];
$updateEmail = $_POST["email"];
//USING A SERVICE ACCOUNT TO CALL GOOGLE CLIENT
putenv('GOOGLE_APPLICATION_CREDENTIALS=/home/myserver/mywebsite/credentialsfile.json');
$client = new Google\Client();
// MY ACCOUNT DATA HERE
$client_id = 'clientid';
$service_account_name = 'serviceaccountemailhere'; //Email Address
$key_file_location = '/home/myserver/mywebsite/mykeyfile.json'; //key.p12
$agencyAdminGroupKey = 'emailforGroupKey#gmial.com'; //agency admins group key
$memberKey = $updateEmail; //$memberemail
$domain = 'yourwebsite.com';
if (getenv('GOOGLE_APPLICATION_CREDENTIALS')) {
// use the application default credentials
$client->useApplicationDefaultCredentials();
} else {
echo missingServiceAccountDetailsWarning();
return;
}
// set the scope(s) that will be used
//$client->setScopes(array('https://www.googleapis.com/auth/admin.directory.group'));
$client->setScopes(array('https://www.googleapis.com/auth/admin.directory.group'));
// this is needed only if you need to perform
// domain-wide admin actions, and this must be
// an admin account on the domain; it is not
// necessary in your example but provided for others
$client->setSubject('yourgoogleaccountemail#domain.com');
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("paste-your-developer-key");
$service = new Google_Service_Directory($client);
$member = new Google_Service_Directory_Member( array('email' => $updateEmail,
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER',
"deliverySettings" => 'DAILY'));
//GET request to google groups server
// $results = $service->members->listMembers($groupKey);
$results = $service->members->insert($agencyAdminGroupKey, $member);
Here are some useful links:
https://github.com/googleapis/google-api-php-client
https://developers.google.com/admin-sdk/directory/v1/quickstart/php
https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/php/latest/class-Google_Service_Directory_Groups.html
https://developers.google.com/admin-sdk/directory/reference/rest/v1/members