Laravel Guzzle Http Auth not work - php

I try to use an API for sending sms. I've followed the code from this example, but converted to Guzzle:
Implementation example in PHP for POST Rest Request
<?php
…....
try
{
//POST
$httpClient = new Zend_Http_Client();
$httpClient->setUri("http://www.web2sms.ro/prepaid/message");
$httpClient->setMethod(Zend_Http_Client::POST);
$httpClient->setHeaders("Content-Type", "application/json");
//method param
$crtDate = new Zend_Date();
$apiKey = ""; //value provided
$nonce = $crtDate->get(Zend_Date::TIMESTAMP);
$method = "POST";
$url = "/prepaid/message";
$sender = "";
$recipient = "07xxxxxxxx";//To be fill in !
$message = "";
$visibleMessage = "How the message do you want to appear on the interface. If empty string than $message value will be shown";
$scheduleDate = ''; //Format yyyy-MM-dd HH:mm:ss
$validityDate = ''; //Format yyyy-MM-dd HH:mm:ss
$callbackUrl = '';
$secret = ""; // value provided
$string = $apiKey . $nonce . $method . $url . $sender . $recipient . $message . $visibleMessage . $scheduleDate . $validityDate . $callbackUrl . $secret;
$signature = hash('sha512', $string);
$httpClient->setAuth($apiKey, $signature);
$data = array(
"apiKey" => $apiKey,
"sender" => $sender,
"recipient" => $recipient,
message" => $message,
"scheduleDatetime" => $scheduleDate,
"validityDatetime" => $validityDate,
"callbackUrl" => $callbackUrl,
"userData" => "",
"visibleMessage" => $visibleMessage,
"nonce" => $nonce);
$httpClient->setRawData(Zend_Json::encode($data));
$httpResponse = $httpClient->request();
var_dump($httpResponse);
var_dump($httpResponse->getBody());
var_dump(json_decode($httpResponse->getBody()));
}
catch (Zend_Http_Client_Exception $e)
{
//
}
My Code with Guzzle:
$apiKey = "xxxxxxxxx";
$nonce = time();
$method = "POST";
$url = "http://www.web2sms.ro/prepaid/message";
$sender = "XXXXXXXX";
$recipient = "0768814244";
$message = "Un mesaj";
$visibleMessage = "How the message do you want to appear on the interface. If empty string than value will be shown";
$secret = "xxxxxxxxxx";
$string = $apiKey . $nonce . $method . $url . $sender . $recipient . $message . $visibleMessage . $secret;
$signature = hash('sha512', $string);
$client = new GuzzleHttp\Client([
'headers' => ['Content-Type' => 'application/json']
]);
$data = array(
"apiKey" => $apiKey,
"sender" => $sender,
"recipient" => $recipient,
"message" => $message,
"visibleMessage" => $visibleMessage,
"nonce" => $nonce);
$body = GuzzleHttp\json_encode($data);
$request = $client->request('POST', 'http://www.web2sms.ro/prepaid/message', ['auth' => [$apiKey, $signature], 'body' => $body]);
But still not working;
I receive this error:
Client error: `POST http://www.web2sms.ro/prepaid/message` resulted in a `401 Unauthorized` response:
{"error":{"code":268435459,"message":"IDS_App_Controller_Rest_Message__E_INVALID_REQUEST_DATA_WRONG_SIGNATURE"}}
What I am getting wrong??

I was able to solve it by changing $url to /prepaid/message.

Related

Invalid signature on amazon v2

I have a problem on setting signature in this part of the guide (http://amazonpaycheckoutintegrationguide.s3.amazonaws.com/amazon-pay-checkout/set-payment-info.html). Here' my code:
<?
header('Content-Type: application/json');
define("STORE_ID", "amzn1.application-oa2-client.fb120c0b541e4007aaf987a73b365a3e");
define("VENDOR_ID", "A6SFQPANHYSL0");
define("PUBLIC_KEY_ID", "AGBUUNBAKQW5OMTKHP5WZH55");
define("PRIVATE_KEY_ID", "AmazonPay_AGBUUNBAKQW5OMTKHP5WZH55.pem");
$method = 'POST';
// API Merchant Scan
$url = 'https://pay-api.amazon.eu/sandbox/v2/checkoutSessions/'.$_GET['amazonCheckoutSessionId'];
$payload = array(
'webCheckoutDetails' => array(
'checkoutResultReturnUrl'=> 'https://a.com/merchant-confirm-page'
),
'paymentDetails' => array(
'paymentIntent'=> 'AuthorizeWithCapture',
'canHandlePendingAuthorization'=>false,
'softDescriptor'=> 'Descriptor',
'chargeAmount'=> array(
'amount'=> '1',
'currencyCode'=> 'EUR'
),
),
'merchantMetadata'=> array(
'merchantReferenceId'=> 'Merchant reference ID',
'merchantStoreName'=> 'Merchant store name',
'noteToBuyer'=> 'Note to buyer',
'customInformation'=> 'Custom information'
)
);
// Convert to json string
$payload = json_encode($payload);
$requestParameters = array();
include 'amazon-pay-api-sdk-php-master/vendor/autoload.php';
$amazonpay_config = array(
'public_key_id' => PUBLIC_KEY_ID,
'private_key' => PRIVATE_KEY_ID,
'region' => 'EU',
'sandbox' => true
);
$client = new Amazon\Pay\API\Client($amazonpay_config);
// Create an array that will contain the parameters for the charge API call
$pre_signed_headers = array();
$pre_signed_headers['Accept'] = 'application/json';
$pre_signed_headers['Content-Type'] = 'application/json';
$pre_signed_headers['X-Amz-Pay-Region'] = 'eu';
$timestamp_data = date("Ymd");
$timestamp_orario = date("His");
$timestamp = $timestamp_data."T".$timestamp_orario."Z";
$signedInput = $client->createSignature($method, $url, $requestParameters, $pre_signed_headers, $payload, $timestamp);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://pay-api.amazon.eu/sandbox/v2/checkoutSessions/'.$_GET['amazonCheckoutSessionId']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$headers = array();
$headers[] = 'Authorization: AMZN-PAY-RSASSA-PSS PublicKeyId=AGBUUNBAKQW5OMTKHP5WZH55, SignedHeaders=accept;content-type;x-amz-pay-date;x-amz-pay-host;x-amz-pay-region, Signature= '.$signedInput;
$headers[] = 'X-Amz-Pay-Date: '.$timestamp;
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$json = json_decode($result);
print_r($json);
?>
The class for $client->createSignature is:
public function createSignature($http_request_method, $request_uri, $request_parameters, $pre_signed_headers, $request_payload, $timeStamp)
{
$rsa = $this->setupRSA();
$pre_signed_headers['X-Amz-Pay-Date'] = $timeStamp;
$pre_signed_headers['X-Amz-Pay-Host'] = $this->getHost($request_uri);
$hashedPayload = $this->hexAndHash($request_payload);
$canonicalURI = $this->getCanonicalURI($request_uri);
$canonicalQueryString = $this->createCanonicalQuery($request_parameters);
$canonicalHeader = $this->getHeaderString($pre_signed_headers);
$signedHeaders = $this->getCanonicalHeadersNames($pre_signed_headers);
$canonicalRequest = (
$http_request_method . "\n" .
$canonicalURI . "\n" .
$canonicalQueryString . "\n" .
$canonicalHeader . "\n" .
$signedHeaders . "\n" .
$hashedPayload
);
$hashedCanonicalRequest = self::AMAZON_SIGNATURE_ALGORITHM . "\n" . $this->hexAndHash($canonicalRequest);
$signature = $rsa->sign($hashedCanonicalRequest);
if ($signature === false) {
throw new \Exception('Unable to sign request, is your RSA private key valid?');
}
return base64_encode($signature);
}
The problem i received from the page i want to laod is:
[reasonCode] => InvalidRequestSignature
[message] => Unable to verify signature, signing String ...
Do you know how i can get a valid signature? I can use the one i got 2 steps before (the one that create the button for amazon pay) but i don't think it is the same.
Thank you for your time.

Non supported claims in JWT implementation

I am implementing JWT in my application using php-jwt library from Firebase. I tried the example in the site and it is working fine.
$token = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);
However if I try to include other claims such as exp or sub, it throws UnexpectedValueException ('Wrong number of segments') exception. Has somebody encountered this issue ? Does the php-jwt library supports only the four claims shown in the example ? The code to receive the token in api is given below:
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
}
else if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} elseif (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
//print_r($requestHeaders);
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
$jwt = $matches[1];
}
}
$key = "example_key";
$decoded = JWT::decode($jwt, $key, array('HS256'));
$decoded_array = (array) $decoded;
If the token is generated using the example in the site, then it works fine. If the token is generated using claims like:
$tokenId = base64_encode(mcrypt_create_iv(32));
$issuedAt = time();
$notBefore = $issuedAt + 3;
$expire = $notBefore + 3600;
$token = array(
"iss" => "http://example.com",
"aud" => "http://example.com",
"iat" => $issuedAt,
"nbf" => $notBefore,
"exp" => $expire,
"gate" => "kanchanjuri",
"tokenId" => $tokenId
);
then the api call fails.
From app, the token is sent s follows:
HttpURLConnection con = null;
URL url = new URL(query);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.addRequestProperty("Authorization", "Bearer " + token);
if (con.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ con.getResponseCode());
}
Thanks

Calling Moodle web service using Unirest

I want to communicate with an installation of Moodle 2.9.
The following sample client is a slight modification of:
https://github.com/moodlehq/sample-ws-clients/blob/master/PHP-REST/client.php
to use Unirest instead of Curl and JSON instead of XML:
$token = 'd1c74d6466daaaaad59b5d99906bfc84';
$domainname = 'http://moodle.example.com';
$functionname = 'core_user_create_users';
// REST RETURNED VALUES FORMAT
$restformat = 'json';
$user1 = new \stdClass();
$user1->username = 'testusername1';
$user1->password = 'testpassword1';
$user1->firstname = 'testfirstname1';
$user1->lastname = 'testlastname1';
$user1->email = 'testemail1#moodle.com';
$user1->auth = 'manual';
$user1->idnumber = 'testidnumber1';
$user1->lang = 'en';
$user1->theme = 'standard';
$user1->timezone = '-12.5';
$user1->mailformat = 0;
$user1->description = 'Hello World!';
$user1->city = 'testcity1';
$user1->country = 'au';
$preferencename1 = 'preference1';
$preferencename2 = 'preference2';
$user1->preferences = array(
array('type' => $preferencename1, 'value' => 'preferencevalue1'),
array('type' => $preferencename2, 'value' => 'preferencevalue2'));
$user2 = new \stdClass();
$user2->username = 'testusername2';
$user2->password = 'testpassword2';
$user2->firstname = 'testfirstname2';
$user2->lastname = 'testlastname2';
$user2->email = 'testemail2#moodle.com';
$user2->timezone = 'Pacific/Port_Moresby';
$users = array($user1, $user2);
$params = array('users' => $users);
/// REST CALL
$serverurl = $domainname . '/webservice/rest/server.php' . '?wstoken=' . $token . '&wsfunction=' . $functionname;
//if rest format == 'xml', then we do not add the param for backward compatibility with Moodle < 2.2
$restformat = ($restformat == 'json') ? '&moodlewsrestformat=' . $restformat : '';
$headers = array('Accept' => 'application/json');
$response = UnirestRequest::post($serverurl . $restformat, $headers, json_encode($params));
On execution I got an error:
"Notice: Array to string conversion"
, allegedly because of the parameters going in the body. So, I figured I had to serialize the body before sending it, but when I tried:
$response = UnirestRequest::post($serverurl . $restformat, $headers, json_encode($params));
I got back from Moodle:
{"exception":"invalid_parameter_exception","errorcode":"invalidparameter","message":"Detectado
valor de par\u00e1metro no v\u00e1lido","debuginfo":"Missing required
key in single structure: users"} ◀"
There must be something I'm not understanding about how exactly the POST request must look like. Any suggestion?
Moodle expects the body of the post to be URL encoded, so your body must be built
using http_build_query($params) (or any other method to encode your data) such as:
$convertedpostdata = implode('&', $params);//where $params is an array
As far as why, I dont really recall, I remember struggling with an implementation a while ago, you can view
[your_moodle_installation.com]/admin/webservice/documentation.php for more documentation, additionally you here's an example of what I did:
https://gist.github.com/Scott972/5d9e9495c1397a2ad728b66288ce1d42

Rewrite an HTTP request for Vuforia

Can anybody help me to rewrite the following request in curl or anything similar which is available in php 5.6? I'm new with http request in PHP and I'm not able to use the HttpRequest class cause it can't be found on the server. Other suggestions are welcome too. Maybe there is already a library?
$path = "content/images/calendarmotiv/";
$fail = true;
$tmp = $_FILES['imagetarget']['tmp_name'];
$name = basename($_FILES['imagetarget']['name']);
if(move_uploaded_file($tmp, $path.$name))
{
// http request body
$now = new DateTime('NOW');
$body = json_encode(array(
"name" => $name,
"width" => 1024.0,
"image_url" => base64_encode($path.$name),
"active_flag" => 1,
"application_metadata_url" => base64_encode($_POST["metadata"]))
);
$http_verb = "POST";
$content_md5 = md5($body);
$content_type = "application/json";
$date = str_replace("+0000", "GMT", $now->format(DateTime::RFC1123));
$request_path = "<a href='https://vws.vuforia.com/targets'> https://vws.vuforia.com/targets</a>";
// auth string for header
$string_to_sign = $http_verb . "\n" . $content_md5 . "\n" . $content_type . "\n" . $date . "\n" . $request_path;
$secret_key = "mykey";
$signature = hash_hmac("sha1", $string_to_sign, $secret_key);
$authstring = "VWS " . $secret_key . ":" . $signature;
// the request
$request = new HttpRequest($request_path, HttpRequest::METH_POST);
$request->setContentType($content_type);
$request->setBody($body);
$request->addHeaders(array(
"Date" => $date,
"Authorization" => $authstring));
$request->send();
echo $request->getRequestMessage();
echo $request->getResponseMessage();
}
I've created a Vuforia client class in PHP for basic operations with Vuforia target database:
https://github.com/FionNoir/VuforiaClient

Codebird library code works outside, but not inside a function

I want to make a function that will send automatic tweet when ever I publish some post on WordPress website. So I have included Codebird library inside functions.php, but I have problem with creating a function for tweeting. The tweeting function doesn't work.
function post_to_twitter($message)
{
$consumer_key = '....';
$consumer_secret = '....';
$access_token = '....';
$access_secret = '....';
\Codebird\Codebird::setConsumerKey($consumer_key, $consumer_secret);
$cb = \Codebird\Codebird::getInstance();
$cb->setToken($access_token, $access_secret);
$params = array(
'status' => $message
);
$reply = $cb->statuses_update($params);
}
$message = 'New post published';
post_to_twitter($message);
When I put it outside the function, it works, like this
$consumer_key = '....';
$consumer_secret = '....';
$access_token = '....';
$access_secret = '....';
$message = 'New post published';
\Codebird\Codebird::setConsumerKey($consumer_key, $consumer_secret);
$cb = \Codebird\Codebird::getInstance();
$cb->setToken($access_token, $access_secret);
$params = array(
'status' => $message
);
$reply = $cb->statuses_update($params);

Categories