Hello I am newbie and using this library
php auth 2.0
which seems to be a good solution for using auth 2.0. I am trying to generate refresh token I can receive it. Here is my code:
OAuth2\Autoloader::register();
// $dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost"
$storage = new OAuth2\Storage\Pdo(array('dsn' => $this->dsn, 'username' => $this->username, 'password' => $this->password));
// Pass a storage object or array of storage objects to the OAuth2 server class
$server = new OAuth2\Server($storage,array('always_issue_new_refresh_token' => true,
'refresh_token_lifetime' => 2419200,));
// Add the "Client Credentials" grant type (it is the simplest of the grant types)
$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
$server->addGrantType(new OAuth2\GrantType\RefreshToken($storage));
Here is request:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,"http://localhost/eventapp/index.php/oauth/handle");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, "grant_type=client_credentials&client_id=ID&client_secret=SECRET");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result=curl_exec($curl);
curl_close ($curl);
$result=get_object_vars(json_decode($result));
print_r($result);
Can anyone help me with this? Please guide me what I am doing wrong here?
$grantType = new OAuth2\GrantType\RefreshToken($storage, array(
'always_issue_new_refresh_token' => true
));
The Refresh Token grant type has the following configuration:
always_issue_new_refresh_token
whether to issue a new refresh token upon successful token request
Default: false
So by default its false,you have make it true.
Also check here
Example Request
$ curl -u TestClient:TestSecret https://api.mysite.com/token -d 'grant_type=password&username=bshaffer&password=brent123'
The access token will then contain a refresh token
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"expires_in":3600,
"token_type": "bearer",
"scope":null,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
}
Related
I try to set my invision board api with OOAuth but I have always this message { "errorCode": "3S290\/B", "errorMessage": "NO_SCOPES" }"
What I insert inside the application
Client type :
Custom Confidential OAuth Client
A server-side app such as a website where the code will be written in a server-side language and stored on a server that no end-user has access to. A client secret will be issued.
Available Grant Types Required (check all the boxes for my test)
Authorization Code
The end-user will be shown a login screen and redirected back to a specified Redirection URI with an Authorization Code in the query string which you will then exchange for an Access Token.
Implicit
The end-user will be shown a login screen and redirected back to a specified Redirection URI with an Access Token in the fragment.
Resource Owner Password Credentials
The end-user will enter their username or email address and password which you will exchange for an Access Token.
Client Credentials
You will make API calls directly with the Client Identifier and Client Secret without any end-user logging in.
Require PKCE for Authorization Code grant?
Not required
Redirection URIs
https://www.example.com/oauth/callback/
*authorization Prompt
If the user has previously authorized, they will be redirected back immediately, without seeing an authorization screen.
Allow users to choose scopes? and Show in Account Settings? ==> no activated
About the scope :
key : profile
Authorized User : access GET selected
/downloads/categories : acces GET selected
Now about my script
/**
* #return mixed
*/
public function getToken()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->communityUrl . 'oauth/token/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'grant_type' => 'client_credentials',
'client_id' => 'xxxxxxxxxxxxx',
'client_secret' => 'xxxxxxxxxxxxx',
]));
// execute cURL
$result = curl_exec($ch);
curl_close($ch);
// decode JSON response
$response = json_decode($result);
return $response->access_token;
}
}
public function getAllCategories()
{
$token = $this->getToken();
if ($token !== null) {
$curl = curl_init($this->communityUrl . 'api' . $this->endpointCategories);
$array = [
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_USERAGENT => "MyUserAgent/1.0",
CURLOPT_HTTPHEADER => array( "Authorization: Bearer {$token}" ),
];
curl_setopt_array($curl, $array);
$response = curl_exec($curl);
$result = json_decode($response, true);
var_dump($response); // the response about the api to display the categories
exit;
return $result;
}
}
I have no idea why I have this message, I suppose there is something happen somewhere
Little help will be welcome
Than you
I am trying to resolve an azure marketplace subscription using the azure fulfilment api. I have followed the instructions on the Microsoft's SaaS fulfilment api's docs but I am not able to resolve the subscription using PHP.
I am able to get access_token and incidentally I am able to use the token and and use this together with the purchase identification token i get from azure portal when the subscriber is re-directed to the SaaS landing page, to get a successful json response when using postman.
I cannot achieve the same success when using PHP. I get a 403 error - Authorization is missing, incorrect or invalid. I am thinking that the query string bit of authorization parameter is malformed. This has nothing to do with privileges or permissions as I am able to get a successful output on Postman. Here is the code
<?php
use Microsoft\Graph\Graph;
use Microsoft\Graph\Http;
use Microsoft\Graph\Model;
use GuzzleHttp\Client;
class GraphHelper {
private static Client $tokenClient;
private static Client $tokenWebClient;
private static string $clientId = '';
private static string $tenantId = '';
private static string $clientSec = '';
private static string $graphUserScopes = '';
private static Graph $userClient;
private static string $userToken;
private static string $resolveToken;
private static string $subToken= '';
public static function initializeGraphForUserAuth(): void {
GraphHelper::$tokenClient = new Client();
GraphHelper::$clientId = $_ENV['CLIENT_ID'];
GraphHelper::$clientSec = $_ENV['CLIENT_SECRET'];
GraphHelper::$tenantId = $_ENV['TENANT_ID'];
GraphHelper::$graphUserScopes = $_ENV['GRAPH_USER_SCOPES'];
GraphHelper::$userClient = new Graph();
}
public static function getUserToken(): void {
//getting the access token
$accessCodeRequestUrl = 'https://login.microsoftonline.com/'.GraphHelper::$tenantId.'/oauth2/token';
$tokenRequestUrl = 'https://marketplaceapi.microsoft.com/api/saas/subscriptions/resolve?api-version=2018-08-31';
$subToken = $_SESSION['subToken'];
$tokenResponse = GraphHelper::$tokenClient->post($accessCodeRequestUrl, [
'form_params' => [
'client_id' => GraphHelper::$clientId,
'grant_type' => 'client_credentials',
'client_secret' => GraphHelper::$clientSec,
'resource' => '20e940b3-4c77-4b0b-9a53-9e16a1b010a7'
],
// These options are needed to enable getting
// the response body from a 4xx response
'http_errors' => false,
'curl' => [
CURLOPT_FAILONERROR => false
]
]);
if ($tokenResponse->getStatusCode() == 200) {
// Return the access_token
$responseBody = json_decode($tokenResponse->getBody()->getContents());
GraphHelper::$resolveToken = $responseBody->access_token;
$resolveAccessToken= $responseBody->access_token;
} else if ($tokenResponse->getStatusCode() == 400) {
// Check the error in the response body
$responseBody = json_decode($tokenResponse->getBody()->getContents());
if (isset($responseBody->error)) {
$error = $responseBody->error;
// authorization_pending means we should keep polling
if (strcmp($error, 'authorization_pending') != 0) {
throw new Exception('Token endpoint returned '.$error, 100);
}
}
}
//resolving the subscription
$resolveResponse = GraphHelper::$tokenClient->post($tokenRequestUrl, [
'form_params' => [
'content-type' => 'application/json',
'authorization' => 'Bearer '.$resolveAccessToken,
'x-ms-marketplace-token'=> $subToken
],
// These options are needed to enable getting
// the response body from a 4xx response
'http_errors' => false,
'curl' => [
CURLOPT_FAILONERROR => false
]
]);
//test whether there is a reponse
return $resolveResponse->getStatusCode(); // this returns a 403 - Authorization is missing, incorrect or invalid.
}
}
?>
I figured out that I needed to use cUrl for option to include authorization and other headers. Postman did this automatically hence the reason I was able to get results with postman and not with PHP. Eventually this code did it for me.
$subToken = rawurldecode($_SESSION['subToken']);
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL, $tokenRequestUrl);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_HTTPHEADER, array ('Authorization: Bearer '.GraphHelper::$resolveToken,
'Content-type: application/json',
'X-ms-marketplace-token:'. $subToken));
curl_setopt($ch, CURLOPT_POST, true);
$results = json_decode (curl_exec ($ch), 1);
if (array_key_exists ('error', $results)){
echo ($results['error']);
die();
}
curl_close($ch);
return $results['subscriptionName'] ;
I found out that the endpoint was not accepting a get request. It threw an error of Subscription resolve not found","target":"subscriptionId","code":"EntityNotFound . However including a post option corrected that and no error was thrown after this. Again when decoding the token from the url - don't use urldecode() use rawurldecode () instead.
I am newbie, working on codeigniter and I am using the razorpay payment gateway apis for transferring the amount using route concept as defined in the razorpay documentation. When I am calling the api using curl I am getting the error:
{
"error": {
"code": "BAD_REQUEST_ERROR",
"description": "Please provide your api key for authentication purposes.",
"source": null,
"step": null,
"reason": null,
"metadata": {}
}
}
the code i used is :
$url = 'https://api.razorpay.com/v1/payments/pay_E8JR8E0XyjUSZd/transfers';
/* Array Parameter Data */
$data = ['account' => 'va_FWSvFCwsaV1w5K', 'amount' => 90, 'currency' => 'INR'];
/* pass encoded JSON string to the POST fields */
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
/* set the content type json */
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json','YOUR_KEY_ID','YOUR_KEY_SECRET'));
/* set return type json */
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
/* execute request */
$result = curl_exec($ch);
/* close cURL resource */
curl_close($ch);
print_r($result);
How should I place my key and secret in curl so that error does not occur.
Please help me out. Thanks in advance.
The error message is pretty self-explanatory. This line:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json','YOUR_KEY_ID','YOUR_KEY_SECRET'));
Should contain your actual key and secret, not your_key_id and your_key_secret placeholder strings. Otherwise, authorization will fail
You will require to encode key:secret in base64 format. And then add another header Authorization to make this API working.
headers = {
"Content-Type": "application/json",
"Authorization": "Basic " + encode_base64(Key:Secret)
}
In your case,
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Basic (encoded_string)'));
Let me know if it works for you!
I am trying to authenticate a user using the php-github-api library. So far I have sent the user to Github to allow my application access and I successfully get a token back. I'm not sure what to do now. Here is my code.
The URL I send the user to Github with.
https://github.com/login/oauth/authorize?scope=repo,user&client_id=<client_id>
Then with the php-github-api I am doing this. The $token variable is the code that is sent in the $_GET array when the user is redirected to the callback.
$client = new \Github\Client();
try {
$auth = $client->authenticate($token, Github\Client::AUTH_HTTP_TOKEN);
} catch (Exception $e) {
dp($e);
}
Does anyone know if this is the correct method to authenticate a user? When I try and call a method the requires an authenicated user I get a 401 status code and an error in return.
Thanks in advance!
Thanks everyone for their suggestions. Seems like you have to feed the access_token into the authenticate method so an easy fix I implemented was a CURL request to grab the access_token then adding it to the authenticate method in the callback.
$token = $_POST['token'];
$params = [
'client_id' => self::$_clientID,
'client_secret' => self::$_clientSecret,
'redirect_uri' => 'url goes here',
'code' => $token,
];
try {
$ch = curl_init('https://github.com/login/oauth/access_token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
$headers[] = 'Accept: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
} catch (\Exception $e) {
dp($e->getMessage());
}
Then in the call back we can call the authenticate method to and cache it somewhere, currently I am doing this in the session.
$client = self::getClient();
$_SESSION['access_token'] = $response->access_token;
try {
$client->authenticate($response->access_token, Github\Client::AUTH_HTTP_TOKEN);
} catch (\Exception $e) {
dp($e->getMessage());
}
So there we have it.
I did try using the HttpClient of the php github api library but I was having some issues so chose a more simple solution.
The problem is that you're using the code you receive after the user authenticates as a $token when you're supposed to use it to get an actual token. Make a post request to https://github.com/login/oauth/access_token with the client_id, client_secret, code (what you were using as the token), state, and redirect_uri.
You'll get back a response in this format access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&scope=user%2Cgist&token_type=bearer
There is this code in the HttpClient.php file that would make getting the token easier than cURLing
public function post($path, $body = null, array $headers = array())
{
return $this->request($path, $body, 'POST', $headers);
}
https://developer.github.com/v3/oauth/#github-redirects-back-to-your-site
Edit: Why the minus one?
What I am trying to do is the following:
I am trying to login to my school site using cURL and grab the schedule to use it for my AI.
So I need to login using my pass and number, but the form on the school site also needs a hidden 'token'.
<form action="index.php" method="post">
<input type="hidden" name="token" value="becb14a25acf2a0e697b50eae3f0f205" />
<input type="text" name="user" />
<input type="password" name="password" />
<input type="submit" value="submit">
</form>
I'm able to successfully retrieve the token. Then I try to login, but it fails.
// Getting the whole website
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.school.com');
$data = curl_exec($ch);
// Retrieving the token and putting it in a POST
$regex = '/<regexThatWorks>/';
preg_match($regex,$data,$match);
$postfields = "user=<number>&password=<secret>&token=$match[1]";
// Should I use a fresh cURL here?
// Setting the POST options, etc.
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
// I won't use CURLOPT_RETURNTRANSFER yet, first I want to see results.
$data = curl_exec($ch);
curl_close($ch);
Well... It doesn't work...
Is it possible the token changes every curl_exec? Because the site doesn't recognize the script the second time...
Should I create a new cURL instance(?) for the second part?
Is there another way to grab the token within 1 connection?
Cookies?
What's the error message you get? Independently of that; your school's website might check the referrer header and make sure that the request is coming from (an application pretending to be...) its login page.
This is how I solved it. The problem was probably the 'not-using-cookies' part.
Still this is probably 'ugly' code, so any improvements are welcome!
// This part is for retrieving the token from the hidden field.
// To be honest, I have no idea what the cookie lines actually do, but it works.
$getToken= curl_init();
curl_setopt($getToken, CURLOPT_URL, '<schoolsite>'); // Set the link
curl_setopt($getToken, CURLOPT_COOKIEJAR, 'cookies.txt'); // Magic
curl_setopt($getToken, CURLOPT_COOKIEFILE, 'cookies.txt'); // Magic
curl_setopt($getToken, CURLOPT_RETURNTRANSFER, 1); // Return only as a string
$data = curl_exec($token); // Perform action
// Close the connection if there are no errors
if(curl_errno($token)){print curl_error($token);}
else{curl_close($token);}
// Use a regular expression to fetch the token
$regex = '/name="token" value="(.*?)"/';
preg_match($regex,$data,$match);
// Put the login info and the token in a post header string
$postfield = "token=$match[1]&user=<number>&paswoord=<mine>";
echo($postfields);
// This part is for logging in and getting the data.
$site = curl_init();
curl_setopt($site, CURLOPT_URL, '<school site');
curl_setopt($site, CURLOPT_COOKIEJAR, 'cookies.txt'); // Magic
curl_setopt($site, CURLOPT_COOKIEFILE, 'cookies.txt'); // Magic
curl_setopt($site, CURLOPT_POST, 1); // Use POST (not GET)
curl_setopt($site, CURLOPT_POSTFIELDS, $postfield); // Insert headers
$forevil_uuh_no_GOOD_purposes = curl_exec($site); // Output the results
// Close connection if no errors
if(curl_errno($site)){print curl_error($site);}
else{curl_close($site);}
As you're building a scraper, you can create your own classes to work for what you need to do in your domain. You can start by creating your own set of request and response classes that deal with what you need to deal with.
Creating your own request class will allow you to implement the curl request the way you need it. Creating your own response class can you help you access/parse the returned HTML.
This is a simple usage example of some classes I've created for a demo:
# simple get request
$request = new MyRequest('http://hakre.wordpress.com/');
$response = new MyResponse($request);
foreach($response->xpath('//div[#id="container"]//div[contains(normalize-space(#class), " post ")]') as $node)
{
if (!$node->h2->a) continue;
echo $node->h2->a, "\n<", $node->h2->a['href'] ,">\n\n";
}
It will return my blogs posts:
Will Automattic join Dec 29 move away from GoDaddy day?
<http://hakre.wordpress.com/2011/12/23/will-automattic-join-dec-29-move-away-from-godaddy-day/>
PHP UTF-8 string Length
<http://hakre.wordpress.com/2011/12/13/php-utf-8-string-length/>
Title belongs into Head
<http://hakre.wordpress.com/2011/11/02/title-belongs-into-head/>
...
Sending a get request then is easy as pie, the response can be easily accessed with an xpath expression (here SimpleXML). XPath can be useful to select the token from the form field as it allows you to query data of the document more easily than with a regular expression.
Sending a post request was the next thing to build, I tried to write a login script for my blog and it turned out to work quite well. I needed to parse response headers as well, so I added some more routines to my request and response class.
# simple post request
$request = new MyRequest('https://example.wordpress.com/wp-login.php');
$postFields = array(
'log' => 'username',
'pwd' => 'password',
);
$request->setPostFields($postFields);
$response = new MyResponse($request->returnHeaders(1)->execute());
echo (string) $response; # output to view headers
Considering your scenario you might want to edit your own request class to better deal with what you need, mine already uses cookies as you're using them, too. So some code based on these classes for your scenario could look like:
# input values
$url = '<schoolsite>';
$user = '<number>';
$password = '<secret>';
# execute the first get request to obtain token
$response = new MyResonse(new MyRequest($url));
$token = (string) $response->xpath('//input[#name="token"]/#value');
# execute the second login post request
$request = new MyRequest($url);
$postFields = array(;
'user' => $user,
'password' => $password,
'token' => $token
);
$request->setPostFields($postFields)->execute();
Demo and code as gist.
If you want to further improve this, the next step is that you create yourself a class for the "school service" that you make use of to fetch the schedule from:
class MySchoolService
{
private $url, $user, $pass;
private $isLoggedIn;
public function __construct($url, $user, $pass)
{
$this->url = $url;
...
}
public function getSchedule()
{
$this->ensureLogin();
# your code to obtain the schedule, e.g. in form of an array.
$schedule = ...
return $schedule;
}
private function ensureLogin($reuse = TRUE)
{
if ($reuse && $this->isLoggedIn) return;
# execute the first get request to obtain token
$response = new MyResonse(new MyRequest($this->url));
$token = (string) $response->xpath('//input[#name="token"]/#value');
# execute the second login post request
$request = new MyRequest($this->url);
$postFields = array(;
'user' => $this->user,
'password' => $this->password,
'token' => $token
);
$request->setPostFields($postFields)->execute();
$this->isLoggedIn = TRUE;
}
}
After you've nicely wrapped the request/response logic into your MySchoolService class you only need to instantiate it with the proper configuration and you can easily use it inside your website:
$school = new MySchoolService('<schoolsite>', '<number>', '<secret>');
$schedule = $school->getSchedule();
Your main script only uses the MySchoolService.
The MySchoolService takes care of making use of MyRequest and MyResponse objects.
MyRequest takes care of doing HTTP requests (here with cUrl) with cookies and such.
MyResponse helps a bit with parsing HTTP responses.
Compare this with a standard internet browser:
Browser: Handles cookies and sessions, does HTTP requests and parses responses.
MySchoolService: Handles cookies and sessions for your school, does HTTP requests and parses responses.
So you now have a school browser in your script that does what you want. If you need more options, you can easily extend it.
I hope this is helpful, the starting point was to prevent written the same lines of cUrl code over and over again and as well to give you a better interface to parse return values. The MySchoolService is some sugar on top that make things easy to deal with in your own website / application code.