I'm trying to make some Rest-API Calls to the Google Calendar API from my Application to show some Calendar Data and I'm slowly but surely a little in despair.
I've activated the API, created Credentials and downloaded the client-secret Json File.
For testing I used Postman to send an example Request to the api like https://www.googleapis.com/calendar/v3/calendars/{calendar-ID}/acl
Because there was no Access Token to in the json file I used "Get new Access Token", entered all the Data from the json and got a Key. But if I use this Key for sending a Request with oAuth2 Authorization and that example API-Call i get a back a 401.
I played around with this for hours without any success. I'm not very experienced with this kind of Authorization and surely missing a point here.
Actually I just want to make some cUrls from my php-script to get some Calendar Data. Maybe someone could describe the steps that are nessecary to get this done.
thank you in advance. :)
The credentials file that you downloaded from google identifies your application to google. It does not give you direct access to an api.
In order to access a google api containing private user data you need to be authenticated using OAuth2 to gain consent of the resource owner to accesses their data.
These links may help you set up postman using the client id and client secret you have from Google developer console.
Google calendar oauth2
Google Oauth2
Postman oauth2
One problem left. Using the access token to get Data via Postman works in between. Also using the refresh-token to get a new acces token.
But in my Curl, when doing the api-request, i still get a 401 back. Refreshing the access token via curl works pretty well, but the actual api-call for getting data seems still not to be on point.
$oCurl = curl_init();
curl_setopt($oCurl, CURLOPT_HTTPHEADER, array(
'Authorization' => 'Bearer '.$token,
));
curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($oCurl, CURLOPT_TIMEOUT, 30);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($oCurl, CURLOPT_URL, $url);
$response = curl_exec($oCurl);
$list = json_decode($response );
so Response is still
[code] => 401
[message] => Login Required
maybe someone has a clue whats wrong here? :)
€ okay, changing 'Authorization' => 'Bearer '.$token, to 'Authorization: Bearer '.$token, made it.
Thanks for your help
Related
So I was trying to use the LinkedIn Developer API to post some text with a image or multiple images at once.
So here's the issue
https://learn.microsoft.com/en-gb/linkedin/consumer/integrations/self-serve/share-on-linkedin
This is the DOCS for the share on LinkedIn that is completely working fine when am posting just text.
But the issue arises when I try to create Post with Image
https://api.linkedin.com/v2/assets?action=registerUpload This API is giving me an error like this.
{
"serviceErrorCode": 65600,
"message": "Invalid access token",
"status": 401
}
Even I refreshed the token to check if there was an issue with my token. My access token is working fine with sharing the text-only post.
If your above API works fine in case then you are registered for uploading file. Then you'll receive the below URL from the response. But they mentioned it with CURL and I want to send a cross-origin request from Axios. I tried a curl converter but that doesn't explain how we will upload the file with the request.
curl -i --upload-file /Users/peter/Desktop/superneatimage.png --header "Authorization: Bearer redacted" 'https://api.linkedin.com/mediaUpload/C5522AQGTYER3k3ByHQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQJbrN86Zm265gAAAWemyz2pxPSgONtBiZdchrgG872QltnfYjnMdb2j3A&app=1953784&sync=0&v=beta&ut=2H-IhpbfXrRow1'
I have the file either in URL or in Base64 format. I don't have a binary file present in my case. Well, I want to send a binary file too for a default case but for most requests, I'll be using the URL for the image.
Thanks for reading the whole question. Please help me with the information you have that can be useful for me.
I was previously able to send curl messages to
http://fcm.googleapis.com/fcm/send
However now I get
403:Forbidden Error
However, the same curl script works if I change http to https.
This restriction seems to have been put in place yesterday.
My source of messages is an arduino which can only handle HTTP and not HTTPS.
Does anybody know if I can still send HTTP requests to FCM via another route?
Ok, I now have a workaround solution for my Arduino ESP Project to use HTTPS with Google Firebase Cloud Messaging.
i thought I would share it for others stuck in the same rut.
In a nutshell, I created a free PHP website, which offered curl functionality, and scripted an HTTP API to accept HTTP requests and forward them onto Google FCM using an HTTPS Connection.
Here are my solution steps:
Sign up to free account aon https://www.000webhost.com
Create/Manage a free subdomain website eg "yourname" (www.yourname.000webhostapp.com)
Dashboard -> Tools -> FileManager -> Upload Files
in your "public_html" folder create a new file named "api.php"
Paste the PHP code below into this file, and Save & Close
Replace your Arduino old code http references for "http://fcm.googleapis.com/fcm/send"
with "http://yourname.000webhostapp.com/api.php"
Job done!
<?php
// This API allows Arduino to send HTTPS FCM messages
// Takes raw data from the incoming HTTP request
$json = file_get_contents('php://input');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
// build the outgoing headers
$hdr_out = array();
$hdr_out[] = 'Content-Type: application/json';
// read incoming header to extract just the auth key
foreach (getallheaders() as $name => $value) {
//echo "$name: $value\n";
if (strtoupper($name) == "AUTHORIZATION") {
$hdr_out[] = 'Authorization: '. $value;
}
}
curl_setopt($curl, CURLOPT_HTTPHEADER, $hdr_out);
$result = curl_exec($curl);
if ($result) {
$response_code= curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
http_response_code($response_code);
}
else {
echo "API Failure";
http_response_code(500);
}
?>
Its my first attempt at writing PHP code, so feel free to suggest any improvements.
I also have an Arduino project (ESP8266 based) that is also sending http (not https) posts to http://fcm.googleapis.com/fcm/send. that has also stopped working.
I was able to confirm via Postman that requests sent to http://fcm.googleapis.com/fcm/send fail with a 403 (Forbidden) response.
I was able to get something working again by adding a fingerprint to the call to the begin method.
http.begin("https://fcm.googleapis.com/fcm/send", "F6:84:98:95:E5:6B:AC:EC:17:79:74:BF:1A:4B:E0:7E:FA:C8:EC:E9");
I was able to find the fingerprint using this site https://www.grc.com/fingerprints.htm
My actual app however is crashing with the the above update, so I still need to dig into this some more. I think there is a bug in the HttpClient that has already been fixed and I am just not picking it up.
Update
The issue with my full Arduino app crashing was due to the https request using too much memory (esp8266's don't have a lot of memory). I looked at a few options that could reduce the memory requirements, but ultimately I decided to go with a similar, but slightly different approach than what Solara07 posted.
Since I already had a raspberry pi running on my network I decided to use that as a proxy.
I installed trafficserver on the raspberry pi and added the following two lines to the /etc/trafficserver/remap.config
map http://192.168.86.77/fcm/send https://fcm.googleapis.com/fcm/send
reverse_map https://fcm.googleapis.com/fcm/send http://192.168.86.77/fcm/send
The required change to my arduino code was the following:
Change:
http_.begin("http://fcm.googleapis.com/fcm/send");
To:
http_.begin("192.168.86.77", 8080, "http://192.168.86.77/fcm/send");
where http_ is the instance of the HTTPClient
and 192.168.86.77 is the private internal address of my raspberry pi
More details and an answer to some problems I had implementing this can be found here.
Set http (http://fcm.googleapis.com/fcm/send) by https (https://fcm.googleapis.com/fcm/send) on API URL.
I followed the Quick Start Guide on Marketo's site for their REST API. This went well. I was able to get a successful response from their website.
Request:
curl https://ABC-DEF-123.mktorest.com/rest/v1/lists.json?access_token=123:ab
Response:
{"requestId":"123#abcf7aff","result":[],"success":true}
However, when I tried the same request the next day, I received:
{"requestId":"123#abc6731ab6f","success":false,"errors":[{"code":"601","message":"Access token invalid"}]}
I logged into the Marketo admin and noticed that the token I copied and pasted out of the dialog box was different. I tried this new one and it worked.
(This is taken from the guide)
I came across another guide on their site that describes a different authentication process. Marketo Authentication Guide
This guide mentions the token that is returned from the API endpoint has an expiration so I suspect that all Marketo tokens expire (or I need to disable this). However, I have not been able to successfully make requests to this endpoint with my client ID and client secret.
Request:
curl https://ABC-DEF-123.mktorest.com/identity/oauth/token?grant_type=client_credentials&client_id=ACLIENTID&client_secret=ACLIENTSECRET
Response:
{"error":"unauthorized","error_description":"An Authentication object was not found in the SecurityContext"}
Any help in the right direction would be appreciated. Thanks in advance.
REST API tokens expire. So you typically will need to request a token for each session.
from your specific installed URL, like: MARKETOURL/identity/oauth/tokengrant_type=client_credentials&client_id=abc&client_secret=xyz
Which will result in (example):
{
"access_token": "1234",
"token_type": "bearer",
"expires_in": 3599,
"scope": "email#email.com"
}
You will need to start out your sessions with this request to do subsequent calls. I have code that runs this first and then requests a new token if it expires. The expires_in field is in seconds.
Source: http://developers.marketo.com/documentation/rest/authentication/
I was not able to figure out why my curl requests were failing, but I was able to successfully call the Marketo API with mrkt, a Ruby Gem for Marketo.
I've looked through the logs of what the gem is generating for requests and they appear to be exactly the same. But at least I now successfully calling Marketo.
You need to use following sequences.
grant_type= client_credentials
client_id =you will get Marketo admin where you generate token
client_secret=you will get Marketo admin where you generate token
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
GET <Identity URL>/oauth/token?grant_type=client_credentials&client_id=<Client Id>&client_secret=<Client Secret>
Your first call failed because your token expires every hour currently, according to Marketo's docs.
Your curl call to get a new token failed because curl (or something) was stripping off the auth arguments. Try wrapping the url in quotes.
curl "https://ABC-DEF-123.mktorest.com/identity/oauth/token?grant_type=client_credentials&client_id=ACLIENTID&client_secret=ACLIENTSECRET"
You can get more information about what curl is sending with the -v flag. Running this would have given you enough information to at least know that your entire url wasn't being passed down to the request.
curl -v https://ABC-DEF-123.mktorest.com/identity/oauth/token?grant_type=client_credentials&client_id=ACLIENTID&client_secret=ACLIENTSECRET
I checked out this link here on SO: Dealing with HTTP content in HTTPS pages
I tried this regarding open protocols from here: http://benpowell.org/https-and-http-the-protocol-less-or-protocol-relative-urls/
But I have only one call to an HTTP url for openweathermap which does not serve up it's content via HTTPS, unless you pay them 500/mo. Can't do it.
So, I need to find a way to bring in the HTTP content for OpenWeatherMap and not generate the "mixed content" error message on "any" browser.
Here's the API call for OWM: http://api.openweathermap.org/data/2.5/weather?lat=32.22&lon=-100.50&APPID=c6fdcf2d49a0bba3e14f310bd3d5cdc2
Any thoughts, anyone?
Thanks, in advance.
Stumbled upon this thread while trying to get my application hosted on heroku while using the Open Weather Map API.
Put this in front of the url:
https://cors-anywhere.herokuapp.com/
so that the url becomes
https://cors-anywhere.herokuapp.com/http://api.openweathermap.org/data/2.5/forecast?
appid=${API_KEY}
Check your application again and note that the openweather url is http again (the way it was originally)! This solution worked for me, although the CORS solution may not last forever.
I was able to get the api to load on my site that enforces https with a little bit of php.
Basically, I curl the http site and store the results on a page on my domain which is https so it works perfect for me.
I wrote a little function to do the work for me
<?php
#Defining the basic cURL function
function curl($url) {
$ch = curl_init(); // Initialising cURL
#Setting cURL's URL option with the $url variable passed into the function
curl_setopt($ch, CURLOPT_URL, $url);
#Setting cURL's option to return the webpage data
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
#Executing the cURL request and assigning the returned data to the $data variable
$data = curl_exec($ch);
#Closing cURL
curl_close($ch);
#Returning the data from the function
return $data;
}
echo $scraped_website = curl("http://www.example.com");
#I use http://api.openweathermap.org/data//2.5/weather?q=Saint+Louis%2C+MO&units=imperial&lang=nl&APPID=b923732c614593659457d8f33fb0d6fd&cnt=6 instead of "http://www.example.com"
?>
#Full snippet
<?php
// Defining the basic cURL function
function curl($url) {
$ch = curl_init(); // Initialising cURL
curl_setopt($ch, CURLOPT_URL, $url); // Setting cURL's URL option with the $url variable passed into the function
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Setting cURL's option to return the webpage data
$data = curl_exec($ch); // Executing the cURL request and assigning the returned data to the $data variable
curl_close($ch); // Closing cURL
return $data; // Returning the data from the function
}
echo $scraped_website = curl("http://www.example.com");
?>
enter code here
Since forecast.io changed into Dark Sky and they don't allow CORS, thus forcing you to implement a server-side application, I looked for a different solution suitable for a small front-end project.
I found apixu.com, which seems to be much better suited for a simple purpose like mine: FreeCodeCamp project.
They provide both, http and https calls. You get 5000 calls per month for free.
I need to post a string from a .NET site to a Classic ASP site which are hosted on the same server (different virtual directories).
https: //example.com/DOTNETSite/Sender.aspx
to
https: //example.com/ClassicASP/SomeFolder/Target.asp
Target.asp page has 3 ways to handle incoming data:
Form Post
Query String
Headers
I cant pass my data in query string. so that option is out. I am trying the Form post method by building a form on the server side and spitting out javascript code to do a form.submit(). But this is causing a internet explorer to throw a Security Alert for the user. We want to avoid this. Please let us know what is the best way to overcome this situation. Thanks a ton.
Right now you are doing:
your server ----> your client/browser ----> their server
Instead you should use:
your server ----> your client/browser ----> your server ----> their server
That is (if it wasn't clear enough), make it send the form to your own server.
When your server receives the form, it should send it to the target server.
On a basic level, this works. However, you may get issues if the user is supposed to be logged in on the 2nd server etc.
I'll try to illustrate an example in PHP:
File: form.html
<form action="send.php" method="post">
....
</form>
File: send.php
<?php
$url='https://example.com/ClassicASP/SomeFolder/Target.asp';
// create new cur connection
$ch=curl_init();
// tell curl target url
curl_setopt($ch, CURLOPT_URL, $url);
// tell curl we will be sending via POST
curl_setopt($ch, CURLOPT_POST, true);
// tell it not to validate ssl cert
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// tell it where to get POST variables from
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
// make the connection
curl_exec($ch);
// close connection
curl_close($ch);
?>