Google Analytics API OAuth after clicking "Allow" cannot connect to local host - google-analytics

I'm trying to obtain an access token for Google Analytics API.
After creating a project in the developers console and granting acess to the Analytics API I reached the "create credentials" step and created new credentials for a web application.
On these credentials I set the Javascript origins to http://localhost:8080 and also http://localhost:5000. Then I set authorized redirect URIs to http://localhost:8080/oauth2callback as well as http://localhost:5000/oauth2callback.
Then, when I attempt to authorize I'm asked to enter my clientId and secret, which I do, then new browser tab opens and I'm asked to choose an account and then after that select "Allow".
Then, when I click "Allow" I'm taken to this page:
I also tried creating credentials for an application type of "other" but the exact same thing happened.
I've found numerous posts on stack overflow about this but none of the answers were able to solve my problem. Not sure which other info to provide. I even tried clearing history and using different browsers but with no success.
How can I give my application authorization to Google Analytics using OAuth?

This issue has nothing to do with localhost or your redirect uris or JavaScript origins. The issue is that your code is not set up to handle the call back from the authentication server. It would have helped if you had posted your code so it will be hard to know what the problem might be.
You should check the official example here Hello analytics js tutorial
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics Reporting API V4</title>
<meta name="google-signin-client_id" content="<REPLACE_WITH_CLIENT_ID>">
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/analytics.readonly">
</head>
<body>
<h1>Hello Analytics Reporting API V4</h1>
<!-- The Sign-in button. This will run `queryReports()` on success. -->
<p class="g-signin2" data-onsuccess="queryReports"></p>
<!-- The API response will be printed here. -->
<textarea cols="80" rows="20" id="query-output"></textarea>
<script>
// Replace with your view ID.
var VIEW_ID = '<REPLACE_WITH_VIEW_ID>';
// Query the API and print the results to the page.
function queryReports() {
gapi.client.request({
path: '/v4/reports:batchGet',
root: 'https://analyticsreporting.googleapis.com/',
method: 'POST',
body: {
reportRequests: [
{
viewId: VIEW_ID,
dateRanges: [
{
startDate: '7daysAgo',
endDate: 'today'
}
],
metrics: [
{
expression: 'ga:sessions'
}
]
}
]
}
}).then(displayResults, console.error.bind(console));
}
function displayResults(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
}
</script>
<!-- Load the JavaScript API client and Sign-in library. -->
<script src="https://apis.google.com/js/client:platform.js"></script>
</body>
</html>

Related

Using Bing maps to track multiple drivers

i am using bing maps with asp .net. i want to track multiple users ( drivers ) . i found a demo on how to track a user in bing website but i didn't figure out how to track specific user with specific id. here is the code to track user
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type='text/javascript'>
var map, watchId, userPin;
function GetMap()
{
map = new Microsoft.Maps.Map('#myMap', {
credentials: ‘Your Bing Maps Key’
});
}
function StartTracking() {
//Add a pushpin to show the user's location.
userPin = new Microsoft.Maps.Pushpin(map.getCenter(), { visible: false });
map.entities.push(gpsPin);
//Watch the users location.
watchId = navigator.geolocation.watchPosition(UsersLocationUpdated);
}
function UsersLocationUpdated(position) {
var loc = new Microsoft.Maps.Location(
position.coords.latitude,
position.coords.longitude);
//Update the user pushpin.
userPin.setLocation(loc);
userPin.setOptions({ visible: true });
//Center the map on the user's location.
map.setView({ center: loc });
}
function StopTracking() {
// Cancel the geolocation updates.
navigator.geolocation.clearWatch(watchId);
//Remove the user pushpin.
map.entities.clear();
}
</script>
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div><br/>
<input type="button" value="Start Continuous Tracking" onclick="StartTracking()" />
<input type="button" value="Stop Continuous Tracking" onclick="StopTracking()"/>
</body>
</html>
The code you provided will show the user where they are on the map. If you want to see the location of multiple drivers on a map, you will need to capture the location of each driver from a device and get that data into a backend service, then have that backend service send the data to the frontend map canvas (i.e. Bing Maps). There are a lot of different ways to do this.
First you need to know how you are going to capture the drivers location. Two common methods:
A mobile app that uses the native geolocation APIs in the background and sends updates to the backend service.
A dedicated IoT device that is either connected to the vehicle or in the vehicle.
A really quick way to do this is to leverage Azure IoT hub for the backend service and IoT central for the frontend. Here is a reference architecture: https://learn.microsoft.com/en-us/azure/architecture/solution-ideas/articles/real-time-asset-tracking-mgmt-iot-central
Bing maps has an open-source project that leverages mobile devices and displays the data on a map: https://github.com/Microsoft/Bing-Maps-Fleet-Tracker

Google sign-in sends multiple requests on redirect

I'm trying to implement Google sign-in on my web application, as an add-on to normal server-side authentication. The problem is,I'm not able to redirect the page to a Servlet to go to the user homepage. Instead, whenever I try to redirect ONCE,I get continuous requests to the next Servlet(I used print statements on the Servlet to check this).It seems as if the page reloads after every request sent to the Servlet. I also tried using form data to fix this, but that doesn't work either.
How do I stop this from happening? I'm a newbie, so any dumbing down will be much appreciated. In case this is a duplicate, please do send the link. I have tried to find a similar question, but have had no luck so far.
Note: I have removed all irrelevant lines of code.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id"
content="CLIENT_ID_HERE">
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
//document.cookie = "emailId=" + profile.getEmail();
redirectPost(profile.getEmail());
//window.location = "http://localhost:8080/auth/gmailhome";
}
function redirectPost(data) {
var inputElement = document.getElementById('emailId');
var form = document.getElementById("gmailLoginForm");
inputElement.value = data;
form.submit();
}
</script>
</head>
<body>
<form method="post" action="gmaillogin" id="gmailLoginForm">
<input type="hidden" id="emailId" name="emailId">
</form>
<div class="g-signin2" data-onsuccess="onSignIn"></div>
</body>
</html>
I figured out how to solve this issue, and it just occurred to me that I can leave this here in case someone needs it in the future.
The problem we have is that onSignin() gets called as long as the user is signed in, and the status of the user doesn't reflect that they are signed in. I'm not sure why the state isn't changed automatically-perhaps there is some other purpose to this, or this is just low-priority right now.
So, what we do is add a listener that monitors whether or not the user is signed-in.
Something like this
function onLoad() {
gapi.load('auth2', function () {
gapi.auth2.init();
gapi.auth2.isSignedIn.listen(function (isSignedIn) {
this.setState({ status: isSignedIn })
})
})
}

Error when loading an external URL in an iframe with Electron

I am trying to create a desktop application using Electron but I am unable to load an external URL like google.com in an iframe.
The code below, inside index.html, triggers an error.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<!-- All of the Node.js APIs are available in this renderer process. -->
<iframe src="http://www.w3schools.com"></iframe>
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</body>
</html>
The error :
index.html:1 Refused to display 'https://www.w3schools.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
www.w3schools.com/ Failed to load resource: net::ERR_BLOCKED_BY_RESPONSE
What is causing this issue and how can I resolve it?
Adding to what has already been answered by Sjoerd Dal.
Adding External URL using IFRAME : Sites block adding their web pages to any other web page, for avoiding click-jacking. This is usually done by :
a. Adding a response in the header. This stops pages which are not whitelisted/not from same-origin to be included in iframes
b. Checking if top window is same as current window.
Now to answer your question, there is actually a very easy way to do that:
const urls = [
"https://www.google.com"
]
const createWindow = () =>{
win = new BrowserWindow({
center: true,
resizable: true,
webPreferences:{
nodeIntegration: false,
show: false
}
});
win.maximize();
win.webContents.openDevTools();
//win.webContents.
console.log(urls[0]);
win.loadURL(urls[0]);
// win.loadURL(url.format({
// pathname: path.join(__dirname,"index.html"),
// protocol: 'file',
// slashes: true
// }));
win.once('ready-to-show',()=>{
win.show()
});
win.on('closed',()=>{
win = null;
});
}
app.on('ready', createWindow);
Most sites these days block other people from iframing them. As you can see with this error, the site only allows iframes coming from the same domain. As an alternative you can use Electron's webview tag which starts the website on a separate thread, sandboxed in its own BrowserWindow. https://electronjs.org/docs/api/webview-tag

Google sign-in for websites - Invalid Request error

I am trying to follow the tutorial for Google Sign-in . I have copied Google's example exactly, but when I press the sign-in button, an "Invalid Request" error is reported.
The Url for my page is ...
https://s3-ap-southeast-2.amazonaws.com/sbd-aws-sdk-delphi-22/index.html
The content of this page is ...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="230599269648-86peetl434op89ug41lg1vv8sjspfupp.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>
function onSignIn(googleUser) {
// Useful data for your client-side scripts:
var profile = googleUser.getBasicProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
console.log('Full Name: ' + profile.getName());
console.log('Given Name: ' + profile.getGivenName());
console.log('Family Name: ' + profile.getFamilyName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: " + profile.getEmail());
// The ID token you need to pass to your backend:
var id_token = googleUser.getAuthResponse().id_token;
console.log("ID Token: " + id_token);
};
</script>
</head>
<body>
Content of the document......
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
Sign out
<script>
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
}
</script>
</body>
</html>
The web application is properly registered with the Google Developer's Console. Here is the registration downloaded in a json format ...
{
"web": {
"client_id": "230599269648-86peetl434op89ug41lg1vv8sjspfupp.apps.googleusercontent.com",
"project_id": "test-federated-login-196400",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": (redacted),
"javascript_origins": [
"https://s3-ap-southeast-2.amazonaws.com"
]
}
}
When a user presses the sign-in button, the pop-up dialog reports a 400 error with text ...
400. That’s an error.
Error: invalid_request
Permission denied to generate login hint for target domain.
... with request details ...
redirect_uri=storagerelay://https/s3-ap-southeast-2.amazonaws.com?id=auth370793
response_type=permission id_token
scope=email profile openid
openid.realm=
client_id=230599269648-86peetl434op89ug41lg1vv8sjspfupp.apps.googleusercontent.com
ss_domain=https://s3-ap-southeast-2.amazonaws.com
fetch_basic_profile=true
gsiwebsdk=2
How do I get this basic example of Google Sign-in on a web page to work?
I have a work-around. I cannot explain why it works and the OP solution does not.
AWS bucket objects have two different URL formats:
https://s3-ap-southeast-2.amazonaws.com/sbd-aws-sdk-delphi-22
http://sbd-aws-sdk-delphi-22.s3-website-ap-southeast-2.amazonaws.com
I've used Google's webmaster Central to claim ownership and to verify ownership of two domains:
https://s3-ap-southeast-2.amazonaws.com/sbd-aws-sdk-delphi-22/
http://sbd-aws-sdk-delphi-22.s3-website-ap-southeast-2.amazonaws.com/
Although of course, I cannot claim https://s3-ap-southeast-2.amazonaws.com
The first form of URL is generally intended for use in API's. The second is intended for use in the browser (although in the second form, only http is allowed, not https).
I've then modified the javascript origins to add the second form ...
{
"web": {
"client_id": "230599269648-86peetl434op89ug41lg1vv8sjspfupp.apps.googleusercontent.com",
"project_id": "test-federated-login-196400",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": (redacted),
"javascript_origins": [
"https://s3-ap-southeast-2.amazonaws.com",
"http://sbd-aws-sdk-delphi-22.s3-website-ap-southeast-2.amazonaws.com"
]
}
}
... and then addressing the page in the browser by the second form ...
http://sbd-aws-sdk-delphi-22.s3-website-ap-southeast-2.amazonaws.com
... I can then sign-in.
I can't sign-out. The sign0out button raises javascript errors, but that is another question for another day.
Morale of the story
When implementing Google Sign-In on an Amazon AWS hosted bucket ...
Use the website hosting form of the url (http://bucket-name.s3-website-region-amazonaws.com)
Claim and verify ownership of the domain in Webmaster central (in the website hosting form)
Use the same url in javascript origins
Don't use the API form of the bucket url.

Send notification to user on facebook for app request?

I have encountered a lot of questions for the same but no where have been given any concrete answer
I am sending invites to Facebook friends say a , b ,c and what should happen is a notification should be displayed for the app request
I have seen this in case of PININTEREST which does the same however I am trying to achieve this in asp.net. I found this demo which is very close to what I want to achieve
The code I have so far is :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head>
<title>Request Example</title>
</head>
<body>
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<p>
<input type="button"
onclick="sendRequestToRecipients(); return false;"
value="Send Request to Users Directly"
/>
<input type="text" value="User ID" name="user_ids" />
</p>
<p>
<input type="button"
onclick="sendRequestViaMultiFriendSelector(); return false;"
value="Send Request to Many Users with MFS"
/>
</p>
<script>
FB.init({
appId : 'XXXXX',
});
function sendRequestToRecipients() {
var user_ids = document.getElementsByName("user_ids")[0].value;
FB.ui({method: 'apprequests',
message: 'XXXXXXX',
to: user_ids,
}, requestCallback);
}
function sendRequestViaMultiFriendSelector() {
FB.ui({method: 'apprequests',
message: 'My Great Request'
}, requestCallback);
}
function requestCallback(response) {
// Handle callback here
}
</script>
</body>
</html>
EDIT:
When i send the request the user does not get it ... No error is displayed either
Here are two things that might be causing your requests not to go through -
Missing or incorrect canvas URL
Application is in sandbox mode
An application that sends requests to users must have a canvas URL specified in the application's settings. When a user acts on a request (accepts it) he/she is redirected to the application and specifically to the canvas URL. By not specifying a canvas URL your request is deemed invalid by Facebook as there is no where to redirect the user to. The canvas URL can not be apps.facebook.com/namespace because your application does not sit on Facebook's domain. You have to set the URL to your domain. The page that you redirect to should again redirect the user back to your application :
if(!strpos($_SERVER['HTTP_REFERER'],"apps.facebook.com")) {
header("location: "._fb_app_path);
exit();
}
An application in sandbox mode when the user being invited is not listed in the appropriate "roles" group in the application settings. Applications in sandbox mode are only accessable to users who are developers, administrators or testers of that application.
I believe the correct method (at least what we use) is:
function invoke_app_request(){
var receiverUserIds = FB.ui({
method: 'apprequests',
message: 'MESSAGE',
data: '',
max_recipients: AN_INT //this is optional
},
function(response) {
//whatever you do here
}
);
}
I read somewhere (don't take it 100%), that displaying notifications on invites is based on Facebook algorithms and it's not displayed on all apps. It has to do something with app activity and history.

Resources