GCM Push Server side, which API Key to use? - php

I'm a bit confused. I have a GCM PHP server side app server that uses a key from Google Developer Console. I can create Android key as per the instructions given in getting started guide here, or I can create a browser key, server key or OAuth key.
Can somebody tell which key I should use on the server side PHP when sending messages via GCM to Android devices?
This is the function that sends the message to GCM
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
Obviously the XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX string is replaced by my API_KEY in the original code.
p.s: My android is registering fine with the GCM, I have the registration id sent to server as well, it's the send message post request that always returns 401 Unauthorized, I'm afraid I'm using a wrong key?
p.s2: I've tried all 3 sort of API_KEYs without success.

Solved
I was concentrating on Android or Server API_KEY but I actually had to use browser key.
Moreover, to test initially I removed all IP addresses from white listing to make sure that's not the factor playing it's role.
Now I have the push service working with above code using Browser API Key and IP restriction in place for white listing.
Cheers :)

Be sure you include the 'Authorization' header with value 'key=APIKEY'.
ApiKey can be either server key or browser key.
If you define IP whitelist for server key, you can only send messages from the specified IPs.

Related

Created a response listening service with php and curl just like paypal IPN

I am new to php web services and i have asked this question before but could not get useful solutions so i have tried to rephrase it. i am trying to listen to a response from an API and update my database like what is done by the paypal IPN service. The script that i have so far works well when you run it in the browser and i am a geting my a json response back via POST, but the API later sends another response without the involvement of the browse/client and i want it to communicate to my php script in the server and update the database. The API has a notifyURL field that it requires for it to send these notifications and i have set it to the same file that sends the request. Below is the code that i have so far:
if($ch !== false){
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Set the content type to application/json
// curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json;odata=verbose',
'Content-length:' . strlen($jsonDataEncoded))
);
}
//Execute the request
$result = curl_exec($ch);
if ($result === false){
curl_close($ch);
echo "Error".curl_errno($ch). "\n";
}else {
curl_close($ch);
$decoded = json_decode($result, true);
// echo '<pre>';
// var_dump($decoded["paymentAmount"]["totalAmountCharged"]);
// die;
$data['unique_id'] = $decoded["clientCorrelator"];
$data['subscriber_number'] = $decoded["endUserId"];
$data['payment_status'] = $decoded["transactionOperationStatus"];
$data['payment_gross'] = $decoded["paymentAmount"]["totalAmountCharged"];
$data['txn_id'] = $decoded["ecocashReference"];
$this->payments->insertTransaction($data);
die;
What do i need to add to the script for me to achieve my goal using curl and php. The API returns the json response below and i am trying to listen for it and update certain fields into the database.
{"id":71109,"version":0,"clientCorrelator":"58ada3aec8615","endTime":null,"startTime":1487774641697,"notifyUrl":"http://website/ecocash_send/transaction","referenceCode":"17589","endUserId":"774705932","serverReferenceCode":"2202201716440169792864","transactionOperationStatus":"PENDING SUBSCRIBER VALIDATION","paymentAmount":{"id":71110,"version":0,"charginginformation":{"id":71112,"version":0,"amount":1,"currency":"USD","description":" Bulk Sms Online payment"},"chargeMetaData":{"id":71111,"version":0,"channel":"WEB","purchaseCategoryCode":"Online Payment","onBeHalfOf":"PAMONMEFT","serviceId":null},"totalAmountCharged":null},"ecocashReference":"MP170222.1644.A00059","merchantCode":"0000","merchantPin":"000","merchantNumber":"771999313","notificationFormat":null,"serviceId":null,"originalServerReferenceCode":null}"
There needs to be nothing special about the script that responds to the PayPal IPN like call.
All it need to do is be there waiting for the other API to launch it, know what parameters to expect, have a robust error reporting mechanism i.e. save the errors somewhere that you can review them later, or email them to an email account you will look at regularly.
Other than that the usual database access code is all that should be necessary.
Of course you cannot get it to throw anything at your browser as there is no browser in the process.

Twitter application oauth started returning error code 89 Invalid or expired token after 1 year working

I've been using code based on Jon Hurlock's Twitter Application-only Authentication App for over a year now with no problem, and about 2 days ago it started returning this error when trying to generate a bearer token:
Invalid or expired token, code:89
My code is slightly altered to force it to check for SSL, since the page is not on an SSL-enabled domain. I have curl pull in the latest cacert.pem file.
This is application level oauth, NOT individual person oauth. So each time a call is made I generate a bearer token, make an API call, and then invalidate the bearer token. You can see his original code here (I pulled the latest version for the part I use): https://github.com/jonhurlock/Twitter-Application-Only-Authentication-OAuth-PHP/blob/master/Oauth.php
THis is the code used to get a bearer token. Note I only have to include the Application's key and secret, there is no user involved and a user never has to allow the app nor authenticate it:
// Step 1
// step 1.1 - url encode the consumer_key and consumer_secret in accordance with RFC 1738
$encoded_consumer_key = urlencode(CONSUMER_KEY);
$encoded_consumer_secret = urlencode(CONSUMER_SECRET);
// step 1.2 - concatinate encoded consumer, a colon character and the encoded consumer secret
$bearer_token = $encoded_consumer_key.':'.$encoded_consumer_secret;
// step 1.3 - base64-encode bearer token
$base64_encoded_bearer_token = base64_encode($bearer_token);
// step 2
$url = "https://api.twitter.com/oauth2/token"; // url to send data to for authentication
$headers = array(
"POST /oauth2/token HTTP/1.1",
"Host: api.twitter.com",
"User-Agent: Twitter App-Only Search",
"Authorization: Basic ".$base64_encoded_bearer_token,
"Content-Type: application/x-www-form-urlencoded;charset=UTF-8"
);
$ch = curl_init(); // setup a curl
curl_setopt($ch, CURLOPT_URL,$url); // set url to send to
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // set custom headers
curl_setopt($ch, CURLOPT_POST, 1); // send as post
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return output
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, "/directory/path/cacert2014.pem");
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
$header = curl_setopt($ch, CURLOPT_HEADER, 1); // send custom headers
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$retrievedhtml = curl_exec ($ch); // execute the curl
curl_close($ch); // close the curl
Here is what I found (using the same library from John Hurlock). The Bearer Token should be cached.
This particular implementation will ask for a new Bearer Token for every request, Twitter expects that we will cache this token and will return errors and sometimes a 403 forbidden if we do not.
In my case I turned off twitter for a period of time on the site, and then after caching the Bearer Token turned it back on. Everything is back for now. You could also switch to a new twitter app in your developer console instead of waiting.
I cached my Token in Memcache, but you may choose to do something different.
Good luck!

https connection passing another server

I want to do the following scenario but i dont really know if this is possible at all or what techniques i need to use:
So im using an external api to store information of my web application. Now i want to send the api request to my server which sends it to the api server maybe by using curl and wait for the response.. when i receive the response i update something at my server like insert row in mysql and send the response back to the requester
Now the api url is using https and my server is currently using http.. will this be a problem to test or do i need https also?
And how should i implement this using php? Maybe some kind of redirect? Or do i have to rebuild the whole request?
Thanks in advance
There are a lot of unknowns about your question that make it hard to answer, but here goes.
You certainly don't have to offer your own application over HTTPS and you can query an HTTPS API and then deliver your own response via HTTP. I should warn you that you are inherently making the external service less secure by doing this. If you are acting as a proxy for the external service, I would suggest that you either get an SSL certificate and do it the proper way.
The lack of details in your question make it hard to answer a specific question, but here is a small code block that should get you started:
<?php
$url = "https://service/endpoint";
$params = array(
'api_token' => 'mytoken',
'param1' => 'myparam',
);
$url .= http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'received error: ' . curl_error($ch) . ' (code: ' . curl_errno($ch);
} else {
echo 'received response: ' . $result;
}
What nate has said is roughly right, but if you want to post from HTTP to HTTPS with cURL, set this option as well:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Which stops cURL from verifying the peer’s certificate (I'm guessing you don't care about using SSL between the second server and the API).
Code on the app server:
$data = http_build_query(
// Your parameters go here
);
file_get_contents('http://middleserverurl.com/?' . $data);
Code on the middle server:
$apiurl = "https://apiurl.com/?" . http_build_query($_GET);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
// Decode the result data here
// Insert into your database here
// Send something back to your app server e.g.:
$data = http_build_query(
// What you want to send back form the result
);
file_get_contents('http://appserverurl.com/?' . $data);

LinkedIn oAuth 2 issue with client_id parameter

I'm trying to create an application on LinkedIn that's using OAuth2 for authentication and am running into some errors. The client runs on an iOS device and uses an oAuth library to make a call to LinkedIn's servers. My iOS client successfully gets the authorization_code. The client application then passes that authorization_code to my server, which attempts to connect to linkedIN again and get the access_token. This step consistently fails, I get the following error from LinkedIn: {"error":"invalid_request","error_description":"missing required parameters, includes an invalid parameter value, parameter more than once. : client_id"}
My POST method to LInkedIN does contain the client_id, it only contains it once, and I've triple checked the values for all the parameters, they are correct. I've also reset the access multiple times from https://www.linkedin.com/secure/settings and I've even created additional applications on LinkedIn, I keep getting the same result.
I've checked other responses, such as this one: unable to retrieve access token linkedin api and tried the suggestions: revoke keys, request new keys etc, nothing seems to be working.
Here is my server code:
$tokenURL = 'https://www.linkedin.com/uas/oauth2/accessToken';
$redirectURL = 'https://staging.textsuggestions.com';
$clientId = '75a4ezqh741sup';
$clientSecret = 'XXXXXXXX';
$tokenArguments = array("grant_type" => "authorization_code",
"code" => $code,
"redirect_uri" => $redirectURL,
"client_secret" => $clientSecret,
"client_id" => $clientId);
// send the request to the server getting data
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenURL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $tokenArguments);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!empty($response["error"])) {
error_log("Error is: " . $response["error"]);
exit (0);
} else {
// no error, get the access_token and do stuff with it
$timeout = $response["expires_in"];
$access_token = $response["access_token"];
}
Ok I realized what I was doing wrong, the client application library that I was using was generating the full access token (not the auth code). So I was trying to pass in the access token in the place of the auth code. The error that I was getting from Linked In was certainly misleading and I should have checked the client library I was using more carefully.
Have you tried to check your code against this code sample?
https://developer.linkedin.com/documents/code-samples
Check that the POST headers include "Content-Type": "application/x-www-form-urlencoded".

Google Maps API Key Error

I'm trying to connect my PHP script to the google maps API using CURL it connects fine but when i pass the API key it says that it is not valid, below is some of the code I'm using to get stats...
<?php
$url = 'https://maps.google.com/maps/api/geocode/json?address={ADDRESS}&sensor=false&key={MY_KEY}';
$cURL = curl_init();
curl_setopt($cURL, CURLOPT_URL, $url);
curl_setopt($cURL, CURLOPT_HTTPGET, true);
curl_setopt($cURL, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($cURL, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Accept: application/json'
));
curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($cURL);
curl_close($cURL);
?>
I have tried configuring my API keys for both server (set by IP address) and browser (set by Domain Name) on the Google API page at https://code.google.com/apis/console/
The problem that I'm having is every time i send a request i get a return JSON message saying:
stdClass Object (
[error_message] => This site or IP is not authorized to use this API key.
[results] => Array (
)
[status] => REQUEST_DENIED
)
If i try to goto the url in a web browser on the computer in question
https://maps.google.com/maps/api/geocode/json?address=The%20White%20House,%20Washington&sensor=false&key={MY_KEY} i get the same problem:
{
"error_message" : "This site or IP is not authorized to use this API key.",
"results" : [],
"status" : "REQUEST_DENIED"
}
Server type:
O/S: Windows Server 2008 R2 x64
Server: UwAmp 2.2.1
PHP: 5.4.15
MySQL: 5.6.11
Thanks in advance for any help!
The API key is not required for your use of google map API. It is a confusing error message that google replies with in this case. Just remove from your URL the '&key={MY_KEY}', and you should be fine.
You could create table location in your mysql.every time you send a request .insert it to databse. after that you can count request by using count record in your database.i used this solution

Categories