I'm trying to create registration using REST API NotificationHub AZURE from PHP API Microsoft
¿Anyone know how it's done?
Regards and thanks!
Generally speaking, there are 3 main steps required to access Notification Hubs REST endpoints:
Parse the connection string
Generate the authorization token
Perform the HTTP call
You can refer to https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-php-backend-how-to/ for more detail.
Meanwhile, you can directly use these PHP sample provided by Azure Team in your application, which can implement your requirements easily.
# build uri
$uri = $this->endpoint . $this->hubPath . "/registrations" . NotificationHub::API_NEW_VERSION;
$ch = curl_init();
$token = $this->generateSasToken($uri);
$headers = [
'Authorization: '. $token,
'Content-Type: application/xml',
'x-ms-version: 2015-01'
];
$request_body = self::requestBodyRegistration($device_type, $tagsOrTagExpression, $device_code );
if( is_null( $request_body ) )
{
return null;
}
curl_setopt_array($ch, array(
CURLOPT_URL => $uri,
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $request_body
));
// Send the request
$response = curl_exec($ch);
// Check for errors
if($response === FALSE){
throw new Exception(curl_error($ch));
}
$info = curl_getinfo($ch);
curl_close($ch);
private function requestBodyRegistration($device_type, $tagsOrTagExpression, $device_code )
{
switch ($device_type) {
case 'apple':
return '<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<AppleRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<Tags>'. $tagsOrTagExpression .'</Tags>
<DeviceToken>'. $device_code .'</DeviceToken>
</AppleRegistrationDescription>
</content>
</entry>';
case 'gcm':
return '<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<GcmRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<Tags>'. $tagsOrTagExpression .'</Tags>
<GcmRegistrationId>'. $device_code .'</GcmRegistrationId>
</GcmRegistrationDescription>
</content>
</entry>';
default:
return null;
}
}
Related
For user requeriments the backend must be PHP and the app client is in Ionic 2. Based on:
https://msdn.microsoft.com/en-us/library/azure/dn223265.aspx
https://github.com/Azure/azure-notificationhubs-samples/tree/master/notificationhubs-rest-php
https://github.com/webwarejp/notificationhubs-rest-php
Create Registration Notification Hub Azure PHP Important
I created this method in php API:
$uri = $this->endpoint . $this->hubPath . "/registrations".NotificationHub::API_VERSION;
/* print($uri); */
$ch = curl_init($uri);
$token = $this->generateSasToken($uri);
$headers = [
'Authorization: '. $token,
'Content-Type: '."application/atom+xml;type=entry;charset=utf-8",
'x-ms-version: 2015-01',
'Content-Length: 0'
];
$body = $this->getXmlAndroid($registrationId, $tag);
print_r($body);
curl_setopt_array($ch, array(
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $body
));
$response = curl_exec($ch);
// Check for errors
if($response === FALSE){
print_r(curl_error($ch));
throw new Exception(curl_error($ch));
}
$info = curl_getinfo($ch);
print_r($info);
curl_close($ch);
The getXmlAndroid method is simple return xml format with GCM ID
private function getXmlAndroid($registrationId){
return '<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<GcmRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<GcmRegistrationId>'.$registrationId.'</GcmRegistrationId>
</GcmRegistrationDescription>
</content>
</entry>';
}
I get the GcmRegistrationId with this function in Ionic 2 app.
import { Push, PushObject, PushOptions } from '#ionic-native/push';
....
const options: PushOptions = {
android: { senderID: 'MyIDFirebaseProject'},
ios: { alert: 'true', badge: true, sound: 'false'},
windows: {}
};
pushObject.on('registration').subscribe((registration: any) => {
console.log(registration.registrationId);
});
The problem is always request to Registration method in Notification API return
[http_code] => 400
Where 400 means the "Invalid request body. The registration could not be created because the request was malformed.". I don't understand why this happen.
Why you send Content-Length: 0 header? It may cause a problem.
I am doing user Basic Auth in PHP and getting the results of the authentication via an XML file which is then parsed into PHP variables.
Here is the PHP code:
<?php
$username = filter_var($_POST['username'], FILTER_SANITIZE_STRING);
$password = filter_var($_POST['password'], FILTER_SANITIZE_STRING);
$str = $username . ":" . $password;
$client_id = md5($str);
$auth_str = base64_encode($str);
$client_id_str = "client-identifier: " . $client_id;
$plex_auth = "authorization: Basic " . $auth_str;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://someurl/sign_in.xml",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
$plex_auth,
$client_id_str,
"header3",
"header4"
),
));
$response = curl_exec($curl);
$xml = simplexml_load_string($response);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
$user_token = $xml->authenticationtoken;
$user_email = $xml->email;
echo $user_email;
echo $user_token;
?>
This is the response in XML:
<?xml version="1.0" encoding="UTF-8"?>
<user email="xyz#gmail.com" id="2567053"
thumb="https://secure.gravatar.com/avatar/somenumber"
username="Admin" title="Admin" cloudSyncDevice=""
authenticationToken="SomeToken" scrobbleTypes="">
<subscription active="1" status="Active" plan="lifetime">
<feature id="pass"/>
<feature id="sync"/>
<feature id="cloudsync"/>
<feature id="home"/>
</subscription>
<profile_settings auto_select_audio="1" auto_select_subtitle="0"
default_audio_language="en" default_subtitle_language="en"/>
<username>Admin</username>
<email>xyx#gmail.com</email>
<joined-at type="datetime">2014-05-08 17:59:24 UTC</joined-at>
<authentication-token>SomeToken</authentication-token>
</user>
Now for some reason while I can extract every other variable from the XML, the authenticationToken refuses to get parsed. when I echo user_token, it's completely empty!
According to the PHP docs examples on SimpleXML:
Accessing elements within an XML document that contain characters not permitted under PHP's naming convention (e.g. the hyphen) can be accomplished by encapsulating the element name within braces and the apostrophe.
So you can access it like this:
$user_token = $xml->{'authentication-token'};
The response in XML you provided does not appear to be a valid xml string.
I was unable to parse it until i added a '>' to the end of the 'user' tag.
Also, as mentioned in the answer before mine, you will need to access object properties that contain special characters with bracers and single qoutes:
$user_token = $xml->{'authentication-token'};
or like this:
$auth_token = 'authentication-token';
$user_token = $xml->$auth_token;
may I need to access to the emailsettings api with POST action in php.
But i always get this error :
failed to open stream: HTTP request failed! HTTP/1.0 415 Unsupported Media Type
Here is my code:
public function addDelegates($account,$delegates,$domain,$tokken) {
foreach ($delegates as $key => $value) {
sleep(5);
$url = "https://apps-apis.google.com/a/feeds/emailsettings/2.0/".$domain."/".$account."/delegation";
$requestXML = '<?xml version="1.0" encoding="utf-8"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">
<apps:property name="address" value="' . $value . '" />
</atom:entry>';
$requestHeaders = array(
'Content-type: application/xml+atom',
'Accept: application/xml+atom',
sprintf('Content-Length: %d', strlen($requestXML))
);
$context = stream_context_create(
array(
'http' => array(
'method' => 'POST',
'header' => implode("\r\n", $requestHeaders),
'content' => $requestXML,
)
)
);
$responseXML = file_get_contents($url, false, $context);
}
I saw that this error means that i may send wrong content type. But i tried application/json, application/xml, text/xml etc..
Nothing is precised about what data we have to send in emailSettings api doc :/
Thanks in advance .
I think content type in your posted code is not correct. change content-type to "application/atom+xml" instead of application/xml+atom. This should resolve your 415 error.
I've created an LTI enabled tool and am having some trouble with sending data back to an LMS such as Desire2Learn. Based on my understanding alone, you generate an XML payload containing the grade item itself and send this via POST back to the LMS using cURL. The problem I'm running into is that my $result variable is returning false and I can't figure it out right now. Here is my code:
session_start();
require_once 'blti/blti.php';
require_once 'blti/blti_util.php';
define('OAUTH_CONSUMER_KEY', 'key');
define('OAUTH_CONSUMER_SECRET', 'secret');
$blti = new BLTI(OAUTH_CONSUMER_SECRET, true, false);
if ($blti->valid) {
$_SESSION['lis_outcome_service_url'] = $_REQUEST['lis_outcome_service_url'];
$_SESSION['lis_result_sourcedid'] = $_REQUEST['lis_result_sourcedid'];
$_SESSION['lis_person_name_given'] = $_REQUEST['lis_person_name_given'];
$_SESSION['oauth_consumer_key'] = $_REQUEST['oauth_consumer_key'];
$_SESSION['oauth_consumer_secret'] = OAUTH_CONSUMER_SECRET;
sendGradeBackToLMS();
}else {
exit($blti->message);
}
function sendGradeBackToLMS() {
$ch = curl_init();
if (!$ch) { exit('curl is not supported!'); }
$url = 'http://localhost/endpoint.php';
$xmldata = getPOXRequest();
$xml = str_replace(
array('MESSAGE_IDENTIFIER', 'SOURCEDID', 'GRADE'),
array(uniqid(), $_SESSION['lis_result_sourcedid'], 0.75),
$xmldata);
$request_headers = array();
$request_headers[] = 'User-Agent: '. $_SERVER['HTTP_USER_AGENT'];
$request_headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $request_headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $xml
));
$results = curl_exec($ch);
curl_close($ch);
echo $results;
}
function getPOXRequest() {
return <<<XML
<?xml version = "1.0" encoding = "UTF-8"?>
<imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
<imsx_POXHeader>
<imsx_POXRequestHeaderInfo>
<imsx_version>V1.0</imsx_version>
<imsx_messageIdentifier>MESSAGE_IDENTIFIER</imsx_messageIdentifier>
</imsx_POXRequestHeaderInfo>
</imsx_POXHeader>
<imsx_POXBody>
<replaceResultRequest>
<resultRecord>
<sourcedGUID>
<sourcedId>SOURCEDID</sourcedId>
</sourcedGUID>
<result>
<resultScore>
<language>en</language>
<textString>GRADE</textString>
</resultScore>
</result>
</resultRecord>
</replaceResultRequest>
</imsx_POXBody>
</imsx_POXEnvelopeRequest>
XML;
}
Just to summarize it up, $blti is an instance that checks if it is a valid Basic LTI launch or not. If that is true, I initialize the SESSION by storing LTI request variables into SESSION variables. Next in the sendGradeBackToLMS() function I send a block of XML data containing the grade item to the path given in $url.
Any kind of input would be helpful!
Thanks!
Try this code,
require_once("ims-blti/OAuthBody.php");
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
} else {
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
}
$method="POST";
$oauth_consumer_secret = $_REQUEST['secret'];
$sourcedid = $_REQUEST['lis_result_sourcedid'];
if (get_magic_quotes_gpc()) $sourcedid = stripslashes($sourcedid);
$oauth_consumer_key = $_REQUEST['key'];
$endpoint = $_REQUEST['lis_outcome_service_url'];
$content_type = "application/xml";
$body = '<?xml version = "1.0" encoding = "UTF-8"?>
<imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/lis/oms1p0/pox">
<imsx_POXHeader>
<imsx_POXRequestHeaderInfo>
<imsx_version>V1.0</imsx_version>
<imsx_messageIdentifier>MESSAGE</imsx_messageIdentifier>
</imsx_POXRequestHeaderInfo>
</imsx_POXHeader>
<imsx_POXBody>
<OPERATION>
<resultRecord>
<sourcedGUID>
<sourcedId>SOURCEDID</sourcedId>
</sourcedGUID>
<result>
<resultScore>
<language>en-us</language>
<textString>GRADE</textString>
</resultScore>
</result>
</resultRecord>
</OPERATION>
</imsx_POXBody>
</imsx_POXEnvelopeRequest>';
if (isset($_REQUEST['grade'])) {
$operation = 'replaceResultRequest';
$postBody = str_replace(
array('SOURCEDID', 'GRADE', 'OPERATION','MESSAGE'),
array($sourcedid, $_REQUEST['grade'], $operation, uniqid()),
$body);
} else {
exit();
}
$response = sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $postBody);
Check this out,
git clone https://github.com/ebinezar/ims-lti.git
I'm trying to perform soap request to web-service written on C# via https. Server uses self-signed certificate.
After many failed attempts with usage of SoapClient I decided to use pure cURL to perfrom request.
My code:
<?php
header('Content-Type: text/plain; charset=utf-8');
$url = 'https://ip:8443/ServiceName';
$admin = 'login';
$password = 'haShedPassw0rdHere';
$post =
'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
// Soap service params xml
</soap:Body>
</soap:Envelope>';
$headers = array(
'Content-type: text/xml;charset="utf-8"',
'Accept: text/xml',
'Cache-Control: no-cache',
'Pragma: no-cache',
'SOAPAction: https://ip:8443/ServiceName',
'Content-length: ' . strlen($post),
);
$curl = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => $admin . ':' . $password,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => '',
CURLOPT_AUTOREFERER => true,
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10
);
curl_setopt_array($curl, $options);
var_dump($response = curl_exec($curl));
?>
Response:
string(370) "
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
a:InvalidSecurity
</faultcode>
<faultstring xml:lang="ru-RU">
Ошибка при проверке безопасности сообщения.
</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>"
Where:
Ошибка при проверке безопасности сообщения.
Means something like:
Communication security check error.
What have I tried:
POST request with a self-signed certificate
How to consume a WCF Web Service that uses custom username validation with a PHP page?
Php SoapClient stream_context option
SOAP authentication with PHP
How can I send SOAP XML via Curl and PHP?
And more of them.
Question: What am I doing wrong?
Regards.
P.S.: Tested with PHP 5.3, PHP 5.4.14, PHP 5.5.1. Results are same.
UPDv1:
C# Source, provided by service support team:
private void Button_SetData_Click(object sender, EventArgs e)
{
eLeed.WebServiceClient client =
new eLeed.WebServiceClient();
client.ClientCredentials.UserName.UserName = "login";
client.ClientCredentials.UserName.Password = "haShedPassw0rdHere";
Stream input = null;
input = GetQuery("ServiceMethod", TextBox_Command.Text);
XmlDocument response = new XmlDocument();
response.PreserveWhitespace = true;
response.Load(client.SetDataContractor(input));
ExeResponse(response);
input.Close();
client.Close();
}
Well, this button is actually working. But how perform something like that in php with cURL ? Especially, how to pass those two lines:
client.ClientCredentials.UserName.UserName = "login";
client.ClientCredentials.UserName.Password = "haShedPassw0rdHere";
Therefore, shouldn't it return message like "invalid credentials" or something?
The error doesnt seem to be on the client side but on the server side. The server says that some security check failed. If it was a client error, you would get nothing but an error by cURL. You get an XML answer.
You should look at the server side.