Litlle problem with integration API -> php - php

I have this code in python that do a request to the API of suap passing the values of dados_usuario, that I tested and is working, but I wanna write the same code in php and I dont getting it, all I got was the token with the follow code, so, anyone could help me with the second part using curl in php?
python code - https://imgur.com/a/LpZ7j4S
import requests
# Obtaining the user's token
url = 'https://suap.ifrn.edu.br/api/v2/autenticacao/token/'
#username and password are your data used to access SUAP
dados_usuario = {
'username': '',
'password': ''
}
requisicao = requests.post(url, data=dados_usuario)
if requisicao.status_code == requests.codes.ok:
token_autenticacao = requisicao.json().get('token')
print ('\n--- Token de Autenticação:\n {}\n\n'.format(token_autenticacao))
# Obtaining User Data.
url = 'https://suap.ifrn.edu.br/api/v2/minhas-informacoes/meus-dados/'
headers = {
'Authorization':'JWT {}'.format(token_autenticacao)
}
requisicao = requests.get(url, headers=headers)
if requisicao.status_code == requests.codes.ok:
retorno_json = requisicao.json()
print ('--- Dados do Usuário Logado:\n{}\n\n'.format(retorno_json))
php code - https://imgur.com/a/tkxb9Gm
<?php
$url = 'https://suap.ifrn.edu.br/api/v2/autenticacao/token/';
$user_data = [
'username' => '',
'password' => ''
];
$ch = curl_init();
//Getting the user token
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $user_data);
$result = curl_exec($ch);
//Token variable
$token = json_decode($result, true);
curl_close($ch);
echo $token["token"]."\n\n";
I need get the user date with php, until now I just have the token, and I need get it with curl.

I got the resolver with this code
$token = "token hide";
$ch = curl_init('https://suap.ifrn.edu.br/api/v2/minhas-informacoes/meus-dados/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: JWT ' . $token
));
$data = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

Related

How to connect with 2ba it's API using PHP

Im trying to connect to the API services of 2ba. Somehow I just can't connect. I get the error: error: "invalid_client"
I dont know what to try, it feels like I need to hash my cliend_secret or complete url but I dont see that in the documentation.
This is my code (PHP):
<?php
// ---- GET TOKEN ----
// Base url for all api calls.
$baseURL = 'https://authorize.2ba.nl';
// Specified url endpoint. This comes after the baseUrl.
$endPoint = '/OAuth/Token';
// Parameters that are required or/and optianal for the endPoint its request.
$parameters = 'grant_type=password&username=abc#abc.com&password=123abc&client_id=myClientID&client_secret=myClientSecret';
// All parts together.
$url = $baseURL . $endPoint . '?' . $parameters;
//Init session for CURL.
$ch = curl_init();
// Options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// Init headers for access to the binance API signed data.
$headers = array();
$headers[] = 'Content-type: application/x-www-form-urlencoded';
$headers[] = 'Content-Length: 0';
// Setting headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute request.
$data = curl_exec($ch);
// If there is an error. Show whats wrong.
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
// Ends the CURL session, frees all resources and deletes the curl (ch).
curl_close($ch);
$result = json_encode($data);
echo($data);
exit();
?>
The authentication is oauth2 and I want to use the "Password Grant" flow since I can login automaticly this way. Also I see in the example code in C# that they encode the url, something im not doing yet but did try. It did not work.
// Using $encodedUrl like this: curl_setopt($ch, CURLOPT_URL, $encodedUrl); but does not work.
$encodedUrl = urlencode($url);
Alright so I fixed it. I now got my access token and am able to recieve data from the API. This is what I did:
// ---- GET TOKEN - FLOW: USER PSW ----
// No changes
$baseURL = 'https://authorize.2ba.nl';
// No changes
$endPoint = '/OAuth/Token';
// $parameters is now an array.
$parameters = array(
'grant_type' => 'password',
'username' => 'myUsername',
'password' => 'myPassword',
'client_id' => 'myClientID',
'client_secret' => 'myClientSecret'
);
// Removed the $parameter part
$url = $baseURL . $endPoint;
//Init session for CURL.
$ch = curl_init();
// Init headers for access to the binance API signed data.
$headers = array();
$headers['Content-Type'] = "application/x-www-form-urlencoded";
// NOTE: http_build_query fixed it.
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parameters)); // Automaticly encodes parameters like client_secret and id.
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute request.
$data = curl_exec($ch);
// If there is an error. Show whats wrong.
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
// Ends the CURL session, frees all resources and deletes the curl (ch).
curl_close($ch);
$result = json_encode($data);
echo($data);
exit();

How do I send this CURL in PHP [duplicate]

Can anyone show me how to do a PHP cURL with an HTTP POST?
I want to send data like this:
username=user1, password=passuser1, gender=1
To www.example.com
I expect the cURL to return a response like result=OK. Are there any examples?
<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
?>
Procedural
// set post fields
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init('http://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
Object oriented
<?php
// mutatis mutandis
namespace MyApp\Http;
class CurlPost
{
private $url;
private $options;
/**
* #param string $url Request URL
* #param array $options cURL options
*/
public function __construct($url, array $options = [])
{
$this->url = $url;
$this->options = $options;
}
/**
* Get the response
* #return string
* #throws \RuntimeException On cURL error
*/
public function __invoke(array $post)
{
$ch = \curl_init($this->url);
foreach ($this->options as $key => $val) {
\curl_setopt($ch, $key, $val);
}
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $post);
$response = \curl_exec($ch);
$error = \curl_error($ch);
$errno = \curl_errno($ch);
if (\is_resource($ch)) {
\curl_close($ch);
}
if (0 !== $errno) {
throw new \RuntimeException($error, $errno);
}
return $response;
}
}
Usage
// create curl object
$curl = new \MyApp\Http\CurlPost('http://www.example.com');
try {
// execute the request
echo $curl([
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
]);
} catch (\RuntimeException $ex) {
// catch errors
die(sprintf('Http error %s with code %d', $ex->getMessage(), $ex->getCode()));
}
Side note here: it would be best to create some kind of interface called AdapterInterface for example with getResponse() method and let the class above implement it. Then you can always swap this implementation with another adapter of your like, without any side effects to your application.
Using HTTPS / encrypting traffic
Usually there's a problem with cURL in PHP under the Windows operating system. While trying to connect to a https protected endpoint, you will get an error telling you that certificate verify failed.
What most people do here is to tell the cURL library to simply ignore certificate errors and continue (curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). As this will make your code work, you introduce huge security hole and enable malicious users to perform various attacks on your app like Man In The Middle attack or such.
Never, ever do that. Instead, you simply need to modify your php.ini and tell PHP where your CA Certificate file is to let it verify certificates correctly:
; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem
The latest cacert.pem can be downloaded from the Internet or extracted from your favorite browser. When changing any php.ini related settings remember to restart your webserver.
A live example of using php curl_exec to do an HTTP post:
Put this in a file called foobar.php:
<?php
$ch = curl_init();
$skipper = "luxury assault recreational vehicle";
$fields = array( 'penguins'=>$skipper, 'bestpony'=>'rainbowdash');
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$url = "http://www.google.com";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
curl_setopt($ch,CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
print "curl response is:" . $response;
curl_close ($ch);
?>
Then run it with the command php foobar.php, it dumps this kind of output to screen:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<body>
A mountain of content...
</body>
</html>
So you did a PHP POST to www.google.com and sent it some data.
Had the server been programmed to read in the post variables, it could decide to do something different based upon that.
It's can be easily reached with:
<?php
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.domain.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export($response);
1.Step by step
Initialize the cURL session:
$url = "www.domain.com";
$ch = curl_init($url);
If your request has headers like bearer token or defining JSON contents you have to set HTTPHEADER options to cURL:
$token = "generated token code";
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // for define content type that is json
'bearer: '.$token, // send token in header request
'Content-length: 100' // content length for example 100 characters (can add by strlen($fields))
)
);
If you want to include the header in the output set CURLOPT_HEADER to true:
curl_setopt($ch, CURLOPT_HEADER, false);
Set RETURNTRANSFER option to true to return the transfer as a string instead of outputting it directly:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
To check the existence of a common name in the SSL peer certificate can be set to 0(to not check the names), 1(not supported in cURL 7.28.1), 2(default value and for production mode):
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
For posting fields as an array by cURL:
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
Execute cURL and return the string. depending on your resource this returns output like result=OK:
$result = curl_exec($ch);
Close cURL resource, and free up system resources:
curl_close($ch);
2.Use as a class
The whole call_cURL class that can be extended:
class class_name_for_call_cURL {
protected function getUrl() {
return "www.domain.com";
}
public function call_cURL() {
$token = "generated token code";
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
$url = $this->getUrl();
$output = $this->_execute($fields, $url, $token);
// if you want to get json data
// $output = json_decode($output);
if ($output == "OK") {
return true;
} else {
return false;
}
}
private function _execute($postData, $url, $token) {
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
Using the class and call cURL:
$class = new class_name_for_call_cURL();
var_dump($class->call_cURL()); // output is true/false
3.One function
A function for using anywhere that needed:
function get_cURL() {
$url = "www.domain.com";
$token = "generated token code";
$postData = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
This function is usable just by:
var_dump(get_cURL());
Curl Post + Error Handling + Set Headers [thanks to #mantas-d]:
function curlPost($url, $data=NULL, $headers = NULL) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if(!empty($data)){
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($ch);
if (curl_error($ch)) {
trigger_error('Curl Error:' . curl_error($ch));
}
curl_close($ch);
return $response;
}
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
function curlPost($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error !== '') {
throw new \Exception($error);
}
return $response;
}
I'm surprised nobody suggested file_get_contents:
$url = "http://www.example.com";
$parameters = array('username' => 'user1', 'password' => 'passuser1', 'gender' => '1');
$options = array('http' => array(
'header' => 'Content-Type: application/x-www-form-urlencoded\r\n',
'method' => 'POST',
'content' => http_build_query($parameters)
));
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
it's simple, it works; I use it in an environment where I control the code at both ends.
even better, use json_decode (and set up your code to return JSON)
$result = json_decode(file_get_contents($url, false, $context), TRUE);
this approach invokes curl behind the scenes, but you don't jump through as many hoops.
Answer refined from this original answer elsewhere on Stack Overflow:
PHP sending variables to file_get_contents()
If the form is using redirects, authentication, cookies, SSL (https), or anything else other than a totally open script expecting POST variables, you are going to start gnashing your teeth really quick. Take a look at Snoopy, which does exactly what you have in mind while removing the need to set up a lot of the overhead.
A simpler answer IF you are passing information to your own website is to use a SESSION variable. Begin php page with:
session_start();
If at some point there is information you want to generate in PHP and pass to the next page in the session, instead of using a POST variable, assign it to a SESSION variable. Example:
$_SESSION['message']='www.'.$_GET['school'].'.edu was not found. Please try again.'
Then on the next page you simply reference this SESSION variable. NOTE: after you use it, be sure you destroy it, so it doesn't persist after it is used:
if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
Here are some boilerplate code for PHP + curl
http://www.webbotsspidersscreenscrapers.com/DSP_download.php
include in these library will simplify development
<?php
# Initialization
include("LIB_http.php");
include("LIB_parse.php");
$product_array=array();
$product_count=0;
# Download the target (store) web page
$target = "http://www.tellmewhenitchanges.com/buyair";
$web_page = http_get($target, "");
...
?>
Examples of sending form and raw data:
$curlHandler = curl_init();
curl_setopt_array($curlHandler, [
CURLOPT_URL => 'https://postman-echo.com/post',
CURLOPT_RETURNTRANSFER => true,
/**
* Specify POST method
*/
CURLOPT_POST => true,
/**
* Specify array of form fields
*/
CURLOPT_POSTFIELDS => [
'foo' => 'bar',
'baz' => 'biz',
],
]);
$response = curl_exec($curlHandler);
curl_close($curlHandler);
echo($response);
If you try to login on site with cookies.
This code:
if ($server_output == "OK") { ... } else { ... }
It May not works if you try to login, because many sites return status 200, but the post is not successful.
The easy way to check if the login post is successful is to check if it setting cookies again. If in output have a Set-Cookies string, this means the posts are not successful and it starts a new session.
Also, the post can be successful, but the status can redirect instead of 200.
To be sure the post is successful try this:
Follow location after the post, so it will go to the page where the post does redirect to:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And than check if new cookies existing in the request:
if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output))
{echo 'post successful'; }
else { echo 'not successful'; }
Easiest is to send data as application/json. This will take an array as input and properly encodes it into a json string:
$data = array(
'field1' => 'field1value',
'field2' => 'field2value',
)
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type:application/json',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resultStr = curl_exec($ch);
return json_decode($resultStr, true);

Workflow Max add job via API

I'm trying to add a job to the Workflow Max API. I seem to be hitting the API but I keep getting the error message:
Message not in expected format. The following required element was missing - Job/ClientID
I'm sure that the client ID is added but something seems to be wrong. This is the code:
function post_job_to_workflow_max($job_data) {
// configure our connection to the api
$api_token = 'API_KEY';
$acc_key = 'ACC_TOKEN';
$url = 'https://api.workflowmax.com/job.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Job data must match the format required by WorkflowMax
// currently accepts XML data
// see: https://www.workflowmax.com/api/job-methods#POST%20add
$xml = new SimpleXMLElement("<Job></Job>");
$xml->addChild('Name', $job_data[0]);
$xml->addChild('Description', $job_data[1]);
$xml->addChild('ClientID', 18754031);
// $clientID = $xml->addChild('Client');
// $clientID->addChild('ID', 18754031);
// $clientID->addChild('Name', "TEST CLIENT");
$xml->addChild('State', 'Planned');
$xml->addChild('StartDate', $job_data[2]);
$xml->addChild('DueDate', $job_data[3]);
// print_r($xml);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
$result = simplexml_load_string($output);
print_r($result);
}
If there's anyone with experience of using WFM, would be good to hear how you approached it.
Thanks
So in answer to my own question, I did finally work this out.
The way I did this was to return the ID of the client from the function I used to post a client to WorkFlow Max. See code:
1) post the client
function post_client_to_workflowmax($client_data) {
// configure our connection to the api
$api_token = 'YOUR_TOKEN';
$acc_key = 'YOUR_KEY';
$url = 'https://api.workflowmax.com/client.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Client data must match the format required by WorkflowMax
// currently accepts XML data
// These indexes match up with how the data has been stored
// see: https://www.workflowmax.com/api/client-methods#POST%20add
$xml = new SimpleXMLElement("<Client></Client>");
$xml->addChild('Name', htmlspecialchars($client_data[2]));
$xml->addChild('Email', htmlspecialchars($client_data[9]));
$xml->addChild('Phone', htmlspecialchars($client_data[10]));
$xml->addChild('Address', htmlspecialchars($client_data[3]) . ' ' . htmlspecialchars($client_data[4]));
$xml->addChild('City', htmlspecialchars($client_data[5]));
$xml->addChild('Postcode', htmlspecialchars($client_data[7]));
$xml->addChild('Country', htmlspecialchars($client_data[8]));
$xml->addChild('IsProspect', 'No');
$contacts = $xml->addChild('Contacts');
$contact = $contacts->addChild('Contact');
$name = $contact->addChild('Name', htmlspecialchars($client_data[0]) . ' ' . htmlspecialchars($client_data[1]));
// POST request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
// Create an array from the data that is sent back from the API
$result = simplexml_load_string($output);
$clientID = NULL;
// here we get the ID created for this client and pass it into the variable $clientID
foreach($result->Client as $k => $v) {
$clientID = $v->ID;
}
return $clientID;
}
We then get that ID passed into our job posting function like so:
2) post a job to WFM
function post_job_to_workflow_max($job_data, $clientID) {
// configure our connection to the api
$api_token = 'YOUR_TOKEN';
$acc_key = 'YOUR_KEY';
$url = 'https://api.workflowmax.com/job.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Job data must match the format required by WorkflowMax
// currently accepts XML data
// see: https://www.workflowmax.com/api/job-methods#POST%20add
$xml = new SimpleXMLElement("<Job></Job>");
$xml->addChild('ClientID', $clientID);
$xml->addChild('Name', htmlspecialchars($job_data[0]));
$xml->addChild('Description', htmlspecialchars($job_data[1]));
$xml->addChild('State', 'Planned');
$xml->addChild('StartDate', htmlspecialchars($job_data[2]));
$xml->addChild('DueDate', htmlspecialchars($job_data[3]));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
$result = simplexml_load_string($output);
}
And then calling these functions looks something like this:
$id = post_client_to_workflowmax($client);
post_job_to_workflow_max($job, $id);
Where $client must be an array of data. This worked for my case but might not work for your particular case so you may need to edit the fields etc.
Hopefully this helps someone who is stuck with the same problem. Not the most elegant code but it gets the job done.

PHP Curl vs Python Requests

I am currently writing a piece of code to interface with an API in Python. Supplied by the company that hosts the API is a PHP script that logs into the API given the correct username and password, retrieved the current event ID (JSON format), and then logs out. This works perfectly.
Currently, I am in the process of writing a script in Python to do the very same thing, the current code is shown below. It logs in and out successfully, however, when it tries to retrieve the current event ID I get the status code 404, suggesting that the URL doesn't exist, despite this same URL working with the PHP code.
PHP Code:
define('BASE_URL', 'https://website.api.com/');
define('API_USER', 'username');
define('API_PASS', 'password');
$cookiefile = tempnam(__DIR__, "cookies");
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefile);
$loginParams = array(
'username' => API_USER,
'password' => API_PASS
);
$obj = CurlPost($ch, BASE_URL . '/api/login', $loginParams);
if( $obj->success )
{
echo 'API login successful.' . PHP_EOL;
}
$obj = CurlGet($ch, BASE_URL . '/api/current-event-id');
echo 'API current event ID: ' . $obj->currentEventId . PHP_EOL;
// logout of the API
$obj = CurlGet($ch, BASE_URL . '/api/logout' );
if( $obj->success )
{
echo 'Logged out successfully.' . PHP_EOL;
}
curl_close($ch);
exit(0);
// -------------------------------------------------------------------------
// Functions
// -------------------------------------------------------------------------
// Run cURL post and decode the returned JSON object.
function CurlPost($ch, $url, $params)
{
$query = http_build_query($params);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, count($query));
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
$output=curl_exec($ch);
$obj = json_decode($output);
return $obj;
}
// Run cURL get and decode the returned JSON object.
function CurlGet($ch, $url)
{
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
$output=curl_exec($ch);
$obj = json_decode($output);
return $obj;
}
Python Code:
import requests
BASE_URL = 'https://website.api.com/';
API_USER = "username";
API_PASS = "password";
headers = {'content-type': 'application/json'}
PARAMS = {'username':API_USER,'password':API_PASS}
session = requests.Session()
# Login
resp = session.post(BASE_URL + '/api/login',data=PARAMS)
if resp.status_code != 200:
print("*** ERROR ***: Login failed.")
else:
print("API login successful.")
resp = session.get(BASE_URL + '/api/current-event-id', headers=headers)
print(resp.status_code)
print(resp.text)
# Logout
resp = session.get(BASE_URL + '/api/logout')
if resp.status_code != 200:
print("*** ERROR ***: Logout failed.")
else:
print("API logout successful.")
It's ideal to change BASE_URL to:
'https://website.api.com'
the code looks fine to me when compared to php and should normally work.(Shouldn't you be passing some kind of authentication like a token?).
try debugging your API using postman.
It turns out that my API will only accept cookies transferred in the header, so I wrote a slight hack that dumped the cookiejar into a string that could be sent in the header file.
cookies = json.dumps(requests.utils.dict_from_cookiejar(resp.cookies));
cookies = cookies.replace('"', '')
cookies = cookies.replace('{', '')
cookies = cookies.replace('}', '')
cookies = cookies.replace(': ', '=')
cookies = cookies.replace(',', ';')
headers = {'Cookie':cookies}
resp = session.get(BASE_URL + '/api/current-event-id', headers=headers)

How can I get an Authentication Token for Microsoft Translator API?

I want to get an Authentication Token for the Microsoft Translator API. This is my code:
<?php
//1. initialize cURL
$ch = curl_init();
//2. set options
//Set to POST request
curl_setopt($ch, CURLOPT_POST,1);
// URL to send the request to
curl_setopt($ch, CURLOPT_URL, 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken');
//return instead of outputting directly
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//whether to include header in the output. here set to false
curl_setopt($ch, CURLOPT_HEADER, 0);
//pass my subscription key
curl_setopt($ch, CURLOPT_POSTFIELDS,array(Subscription-Key => '<my-key>'));
//CURLOPT_SSL_VERIFYPEER- Set to false to stop verifying certificate
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//3. Execute the request and fetch the response. check for errors
$output = curl_exec($ch);
if ($output === FALSE) {
echo "cURL Error" . curl_error($ch);
}
//4. close and free up the curl handle
curl_close($ch);
//5. display raw output
print_r($output);
?>
it gives me the following error:
{ "statusCode": 401, "message": "Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API." }
which could mean that the key is invalid according to the website below, but I ensured the key is valid on the same website.
http://docs.microsofttranslator.com/oauth-token.html
I did find some examples online on how to get the Authenticationtoken, but they are outdated.
How can I get the AuthenticationToken/achieve that microsoft recognises my key?
You're passing the subscription-key wrong -
The subscription key should passed in the header (Ocp-Apim-Subscription-Key) or as a querystring parameter in the URL ?Subscription-Key=
And you should use Key1 or Key2 generated by the Azure cognitive service dashboard.
FYI - M$ has made a token generator available for testing purposes, this should give you a clue which keys are used for which purpose:
http://docs.microsofttranslator.com/oauth-token.html
Here's a working PHP script which translates a string from EN to FR (it's based on an outdated WP plugin called Wp-Slug-Translate by BoLiQuan which I've modified for this purpose):
<?php
define("CLIENTID",'<client-name>'); // client name/id
define("CLIENTSECRET",'<client-key>'); // Put key1 or key 2 here
define("SOURCE","en");
define("TARGET","fr");
class WstHttpRequest
{
function curlRequest($url, $header = array(), $postData = ''){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if(!empty($header)){
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
if(!empty($postData)){
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($postData) ? http_build_query($postData) : $postData);
}
$curlResponse = curl_exec($ch);
curl_close($ch);
return $curlResponse;
}
}
class WstMicrosoftTranslator extends WstHttpRequest
{
private $_clientID = CLIENTID;
private $_clientSecret = CLIENTSECRET;
private $_fromLanguage = SOURCE;
private $_toLanguage = TARGET;
private $_grantType = "client_credentials";
private $_scopeUrl = "http://api.microsofttranslator.com";
private $_authUrl = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
// added subscription-key
private function _getTokens(){
try{
$header = array('Ocp-Apim-Subscription-Key: '.$this->_clientSecret);
$postData = array(
'grant_type' => $this->_grantType,
'scope' => $this->_scopeUrl,
'client_id' => $this->_clientID,
'client_secret' => $this->_clientSecret
);
$response = $this->curlRequest($this->_authUrl, $header, $postData);
if (!empty($response))
return $response;
}
catch(Exception $e){
echo "Exception-" . $e->getMessage();
}
}
function translate($inputStr){
$params = "text=" . rawurlencode($inputStr) . "&from=" . $this->_fromLanguage . "&to=" . $this->_toLanguage;
$translateUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?$params";
$accessToken = $this->_getTokens();
$authHeader = "Authorization: Bearer " . $accessToken;
$header = array($authHeader, "Content-Type: text/xml");
$curlResponse = $this->curlRequest($translateUrl, $header);
$xmlObj = simplexml_load_string($curlResponse);
$translatedStr = '';
foreach((array)$xmlObj[0] as $val){
$translatedStr = $val;
}
return $translatedStr;
}
}
function bing_translator($string) {
$wst_microsoft= new WstMicrosoftTranslator();
return $wst_microsoft->translate($string);
}
echo bing_translator("How about translating this?");
?>
Add your key also in the URL.
curl_setopt($ch, CURLOPT_URL, 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key={your key}');
But leave it also in the CURLOPT_POSTFIELDS.

Categories