API key not valid error when trying to get profile data - javascript

I'm trying to test Google login API. I want to retrieve some basic data after the client logs.
I created a Google API Console project and client ID (https://developers.google.com/identity/sign-in/web/devconsole-project)
Here is google official code (https://developers.google.com/api-client-library/javascript/samples/samples#LoadinganAPIandMakingaRequest):
<html>
<head>
</head>
<body>
<script type="text/javascript">
function handleClientLoad() {
// Loads the client library and the auth2 library together for efficiency.
// Loading the auth2 library is optional here since `gapi.client.init` function will load
// it if not already loaded. Loading it upfront can save one network request.
gapi.load('client:auth2', initClient);
}
function initClient() {
// Initialize the client with API key and People API, and initialize OAuth with an
// OAuth 2.0 client ID and scopes (space delimited string) to request access.
gapi.client.init({
apiKey: '5v2RzP7-xyQGNjxrD5suoPL9',
discoveryDocs: ["https://people.googleapis.com/$discovery/rest?version=v1"],
clientId: '298062822261-e5c09q8191mkho0o7n3n3obiq2eq2p3f.apps.googleusercontent.com',
scope: 'profile'
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
});
}
function updateSigninStatus(isSignedIn) {
// When signin status changes, this function is called.
// If the signin status is changed to signedIn, we make an API call.
if (isSignedIn) {
makeApiCall();
}
}
function handleSignInClick(event) {
// Ideally the button should only show up after gapi.client.init finishes, so that this
// handler won't be called before OAuth is initialized.
gapi.auth2.getAuthInstance().signIn();
}
function handleSignOutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function makeApiCall() {
// Make an API call to the People API, and print the user's given name.
gapi.client.people.people.get({
resourceName: 'people/me'
}).then(function(response) {
console.log('Hello, ' + response.result.names[0].givenName);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
<button id="signin-button" onclick="handleSignInClick()">Sign In</button>
<button id="signout-button" onclick="handleSignOutClick()">Sign Out</button>
</body>
</html>
ClientId and apikey are from my google api.
I receive error 400
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developers console",
"url": "https://console.developers.google.com"
}
]
}
]
}
}
I don't understand what's wrong whit my api key. I followed all the steps from google documentation.

It seems you are using the client secret as API key. Isn't it?
To obtain an API key you must create it.
Under credentials (dev console) click on create credential, and then 'API Key'

Related

How to create new property in google analytics using javascript code

This is my first time using analytics api to create new property
I got the below code from here
developers.google.com/analytics/devguides/config/mgmt/v3/mgmtReference/management/webproperties/insert
window.onload = function insertProperty() {
var request = gapi.client.analytics.management.webproperties.insert(
{
'accountId': '123456789',
'resource': {
'websiteUrl': 'http://www.examplepetstore.com',
'name': 'Example Store'
}
});
request.execute(function (response) { console.log(response);});
}
<script src="https://apis.google.com/js/api.js"></script>
when i run the code with valid account id ex:'123456789'
I am getting this error
Uncaught TypeError: Cannot read properties of undefined (reading 'analytics') at insertProperty
what should i do to create new property using this code
The below code is the setup of authorization and rest code
// Replace with your client ID from the developer console.
var CLIENT_ID = '';
// Set authorized scope.
var SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
function authorize(event) {
// Handles the authorization flow.
// `immediate` should be false when invoked from the button click.
var useImmdiate = event ? false : true;
var authData = {
client_id: CLIENT_ID,
scope: SCOPES,
immediate: useImmdiate
};
gapi.auth.authorize(authData, function(response) {
var authButton = document.getElementById('auth-button');
if (response.error) {
authButton.hidden = false;
}
else {
authButton.hidden = true;
queryAccounts();
}
});
}
function queryAccounts() {
// Load the Google Analytics client library.
gapi.client.load('analytics', 'v3').then(function() {
// Get a list of all Google Analytics accounts for this user
gapi.client.analytics.management.accounts.list().then(handleAccounts);
});
}
function handleAccounts(response) {
// Handles the response from the accounts list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account.
var firstAccountId = response.result.items[0].id;
// Query for properties.
queryProperties(firstAccountId);
} else {
console.log('No accounts found for this user.');
}
}
function queryProperties(accountId) {
// Get a list of all the properties for the account.
gapi.client.analytics.management.webproperties.list(
{'accountId': accountId})
.then(handleProperties)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProperties(response) {
// Handles the response from the webproperties list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account
var firstAccountId = response.result.items[0].accountId;
// Get the first property ID
var firstPropertyId = response.result.items[0].id;
// Query for Views (Profiles).
queryProfiles(firstAccountId, firstPropertyId);
} else {
console.log('No properties found for this user.');
}
}
function queryProfiles(accountId, propertyId) {
// Get a list of all Views (Profiles) for the first property
// of the first Account.
gapi.client.analytics.management.profiles.list({
'accountId': accountId,
'webPropertyId': propertyId
})
.then(handleProfiles)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProfiles(response) {
// Handles the response from the profiles list method.
if (response.result.items && response.result.items.length) {
// Get the first View (Profile) ID.
var firstProfileId = response.result.items[0].id;
// Query the Core Reporting API.
queryCoreReportingApi(firstProfileId);
} else {
console.log('No views (profiles) found for this user.');
}
}
function queryCoreReportingApi(profileId) {
// Query the Core Reporting API for the number sessions for
// the past seven days.
gapi.client.analytics.data.ga.get({
'ids': 'ga:' + profileId,
'start-date': '7daysAgo',
'end-date': 'today',
'metrics': 'ga:sessions'
})
.then(function(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
})
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
// Add an event listener to the 'auth-button'.
document.getElementById('auth-button').addEventListener('click', authorize);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics - A quickstart guide for JavaScript</title>
</head>
<body>
<button id="auth-button" hidden>Authorize</button>
<h1>Hello Analytics</h1>
<textarea cols="80" rows="20" id="query-output"></textarea>
<script src="https://apis.google.com/js/client.js?onload=authorize"></script>
</body>
</html>
yes i did , when i click on Authorize i got this Error {error: {code: 403, message: "Request had insufficient authentication scopes.",…}}
not sure why..?
The developer hasn’t given you access to this app. It’s currently being tested and it hasn’t been verified by Google
The issue is that your project is still in testing, you need to add users who you want to grant permission to test your app.
Go to google cloud console Under consent screen look for the button that says "add Users" add the email of the user you are trying to run the app with.
Understanding Property, Account, and View in Google Analytics
Your Analytics profile consists of 3 different components. They are account, property, and view (if you’re using Universal Analytics).
Here’s a closer look at each of them:
Account: You should have at least one account to access the analytics report.
Property: A property can be a website or a mobile app that you’d like to track in Google Analytics and has a unique tracking ID.
View: A view is the access point for your reports if you’re using Universal Analytics. For example, within a property you can have different views for viewing all the data for your website, viewing only a specific subdomain, like blog.example.com, or viewing only Google Ads traffic. Views do not exist in Google Analytics 4.

"can't access property "getAuthInstance", gapi.auth2 is undefined" error while trying to use YouTube data API

so I'm kinda new to API and stuffs like this. Recently I've got a task to list videos from a specific Youtube channel. So the workaround I got is to first collect the id of uploads playlist, then get all videos from that playlist to show them. But the thing is I couldn't go so far, I first got the code from Googles API documentation, did some edits (my api key and stuff like this) and when I run I get this error:
Uncaught TypeError: can't access property "getAuthInstance", gapi.auth2 is undefined
here's the code i'm using (i'll delete my API Key, so don't think its the error):
<script src="https://apis.google.com/js/api.js"></script>
<script>
/**
* Sample JavaScript code for youtube.channels.list
* See instructions for running APIs Explorer code samples locally:
* https://developers.google.com/explorer-help/guides/code_samples#javascript
*/
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({
scope: "https://www.googleapis.com/auth/youtube.readonly"
})
.then(function() {
console.log("Sign-in successful");
},
function(err) {
console.error("Error signing in", err);
});
}
function loadClient() {
gapi.client.setApiKey("my API key was here");
return gapi.client.load("https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest")
.then(function() {
console.log("GAPI client loaded for API");
},
function(err) {
console.error("Error loading GAPI client for API", err);
});
}
// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
return gapi.client.youtube.channels.list({
"part": [
"contentDetails"
],
"id": [
"My Channel ID was here"
]
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) {
console.error("Execute error", err);
});
}
/*gapi.load("client:auth2", function() {
gapi.auth2.init({
client_id: "YOUR_CLIENT_ID"
});
});*/
</script>
<button onclick="authenticate().then(loadClient)">authorize and load</button>
<button onclick="execute()">execute</button>
from the looks of the error it seea ms to me that there's problem with api.js library or maybe there supposed to be another function I need to execute before calling getAuthInstance. I don't have any idea what is happening so hopefully someone can explain to me what is happening, thanks
I don't know much about this stuff myself so I went to the docs and found this section for you:
https://developers.google.com/identity/sign-in/web/reference#gapiauth2getauthinstance
Turns out you need to initialise auth first - the bit you've commented out at the bottom of your code:
/*gapi.load("client:auth2", function() {
gapi.auth2.init({
client_id: "YOUR_CLIENT_ID"
});
});*/
Give that a test and see what you get :D

JQuery get to .Net Web Api using AAD throws 401 invalid_token / the issuer is invalid

I'm trying to create a simple .Net Core Web Api in Azure to test authentication using JQuery. I managed to resolve the CORS issue but I keep getting a 401 "the issuer is invalid" error when trying to use the bearer token. I was able to test the Web Api using Postman and a secret but not when using JQuery and AAD. I lifted some demo SPA code from a sample that works separately but not when I keep the client and Web Api in separate projects. I thought maybe it was required for me to use the client ID of the Web Api to get my token but that doesn't seem to have any effect. The controller couldn't be any more basic.
namespace test_core_web_api_spa.Controllers
{
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
// For more information on protecting this API from Cross Site Request Forgery (CSRF) attacks, see https://go.microsoft.com/fwlink/?LinkID=717803
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
// For more information on protecting this API from Cross Site Request Forgery (CSRF) attacks, see https://go.microsoft.com/fwlink/?LinkID=717803
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
// For more information on protecting this API from Cross Site Request Forgery (CSRF) attacks, see https://go.microsoft.com/fwlink/?LinkID=717803
}
}
}
And the startup for the Web Api is basic.
namespace test_core_web_api_spa
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseCors(options => options.WithOrigins("https://localhost:44399", "https://localhost:44308").AllowAnyMethod().AllowAnyHeader());
app.UseMvc();
}
}
}
The HTML page was copied from a SPA demo using AAD.
<!DOCTYPE html>
<html>
<head>
<title>Test API Call</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse"
data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/#Home">test api call</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Home</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="app-user navbar-text"></li>
<li>Logout</li>
<li>Login</li>
</ul>
</div>
</div>
</div>
<div id="divHome" class="container-fluid">
<div class="jumbotron">
<h5 id="WelcomeMessage"></h5>
<div class="text-hide">Surname: <span id="userSurName"></span><span id="userEmail"></span></div>
<h2>test page</h2>
</div>
<div>
<br />
Call Api
<br />
<p class="view-loading">Loading...</p>
<div class="app-error"></div>
<br />
<span id="data-container"></span>
</div>
<br />
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.1.3/js/msal.js" integrity="sha384-m/3NDUcz4krpIIiHgpeO0O8uxSghb+lfBTngquAo2Zuy2fEF+YgFeP08PWFo5FiJ" crossorigin="anonymous"></script>
<script src="js/rest_api.js"></script>
</body>
</html>
And the Javascript was also borrowed from the SPA AAD demo in GitHub.
// the AAD application
var clientApplication;
(function () {
console.log("document ready done");
window.config = {
clientID: 'clientidof_web_api_in_azure'
};
const loginRequest = {
scopes: ["openid", "profile", "User.Read"]
};
const tokenRequest2 = {
scopes: ["https://myPortal.onmicrosoft.com/test_core_web_api_spa"]
};
var scope = [window.config.clientID];
const msalConfigDemo = {
auth: {
clientId: "myclientid",
authority: "https://login.microsoftonline.com/mytenantid",
consentScopes: ["user.read","https://myportal.onmicrosoft.com/test_core_web_api_spa/user_impersonation"],
validateAuthority: true
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: false
}
};
function authCallback(errorDesc, token, error, tokenType) {
//This function is called after loginRedirect and acquireTokenRedirect. Not called with loginPopup
// msal object is bound to the window object after the constructor is called.
if (token) {
log("authCallback success");
console.log({ 'token': token });
console.log({ 'tokenType': tokenType });
}
else {
log(error + ":" + errorDesc);
}
}
if (!clientApplication) {
clientApplication = new clientApplication = new Msal.UserAgentApplication(msalConfigDemo, msalConfigDemo, authCallback);
} else {
console.log({ 'clientApplication': clientApplication });
}
// Get UI jQuery Objects
var $panel = $(".panel-body");
var $userDisplay = $(".app-user");
var $signInButton = $(".app-login");
var $signOutButton = $(".app-logout");
var $errorMessage = $(".app-error");
var $btnCallApiTest = $(".btnCallApiTest");
onSignin(null);
// Handle Navigation Directly to View
window.onhashchange = function () {
loadView(stripHash(window.location.hash));
};
window.onload = function () {
$(window).trigger("hashchange");
};
$btnCallApiTest.click(function () {
call_api_test();
});
// Register NavBar Click Handlers
$signOutButton.click(function () {
clientApplication.logout();
});
$signInButton.click(function () {
clientApplication.loginPopup(loginRequest).then(onSignin);
});
function stripHash(view) {
return view.substr(view.indexOf('#') + 1);
}
function call_api_test() {
// Empty Old View Contents
var $dataContainer = $(".data-container");
$dataContainer.empty();
var $loading = $(".view-loading");
clientApplication.acquireTokenSilent(tokenRequest2)
.then(function (token) {
getTodoList(token.accessToken, $dataContainer, $loading);
}, function (error) {
clientApplication.acquireTokenPopup(tokenRequest2).then(function (token) {
getTodoList(token.accessToken, $dataContainer, $loading);
}, function (error) {
printErrorMessage(error);
});
});
}
function getTodoList(accessToken, dataContainer, loading) {
// Get TodoList Data
let urlstring = 'https://localhost:44363/api/values';
console.log({ 'accessToken': accessToken });
$.ajax({
type: "GET",
url: urlstring,
headers: {
'Authorization': 'Bearer ' + accessToken,
},
}).done(function (data) {
// Update the UI
console.log({ 'data': data });
loading.hide();
dataContainer.html(data);
}).fail(function (jqXHR, textStatus) {
printErrorMessage('Error getting todo list data statusText->' + textStatus + ' status->' + jqXHR.status);
console.log({ 'jqXHR': jqXHR });
loading.hide();
}).always(function () {
// Register Handlers for Buttons in Data Table
//registerDataClickHandlers();
});
}
function printErrorMessage(mes) {
var $errorMessage = $(".app-error");
$errorMessage.html(mes);
}
function onSignin(idToken) {
// Check Login Status, Update UI
var user = clientApplication.getUser();
if (user) {
$userDisplay.html(user.name);
$userDisplay.show();
$signInButton.hide();
$signOutButton.show();
} else {
$userDisplay.empty();
$userDisplay.hide();
$signInButton.show();
$signOutButton.hide();
}
}
}());
Logging in does work with AAD and pulls back my email address. I do see a token created and being passed to the Web Api. But then it gives the "issuer is invalid" 401 error. I'm the client Id of the Web Api when making my token request so I'm not sure what else could be changed.
Per comments I have tried to pass a scope to the loginPopup call.
$signInButton.click(function () {
clientApplication.loginPopup(requestObj).then(onSignin);
});
However the only value that works gives the same results:
var requestObj = ["web-api-client-id"];
I've tried the URL of the local web service running including combinations using https://localhost:44399/.default but that throws immediate errors before getting a token with a message like the resource principal named https://localhost:44399 was not found in the tenant. If the problem is the scope setting in this call then I am not sure what value to use to make this work locally when debugging. As a side note I found other Github samples using a format of
var requestObj = {scopes: ["api://clientid/access_as_user"]};
but these fail to execute saying API does not accept non-array scopes. I might ask this in a separate thread.
Update Nov 13
I switched from 0.2.3 of MSAL to 1.1.3 and then updated the logic to reflect the changes made in the different versions.
I also confirmed the client app has API permissions to the web api. I added a new scope to the web api called "user_impersonation". The existing "api-access" was locked to admin control in my tenant.
When trying to use the form "api//" it does not find the resource. Here are the values I tried which all get the same error. I think this format is legacy.
scopes: ["api://web-api-clientid"]
scopes: ["api://web-api-clientid/api-access"]
scopes: ["api://web-api-clientid/user_impersonation"]
scopes: ["api://web-api-clientid/.default"]
ServerError: AADSTS500011: The resource principal named api://web-api-clientid was not found in the tenant named my-tenant-id. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
When trying these scopes the error was 401 audience is invalid.
scopes: ["https://myPortal.onmicrosoft.com/test_core_web_api_spa/user_impersonation"]
scopes: ["https://myPortal.onmicrosoft.com/test_core_web_api_spa/.default"]
401 www-authenticate: Bearer error="invalid_token", error_description="The audience is invalid"
"aud": "https://myPortal.onmicrosoft.com/test_core_web_api_spa"
When trying these scopes the error message gets my client app correct but again doesn't seem to think my web api app exists on my portal.
scopes: ["https://myPortal.onmicrosoft.com/test_core_web_api_spa"]
scopes: ["https://myPortal.onmicrosoft.com/test_core_web_api_spa","user_impersonation"]
ServerError: AADSTS650053: The application 'demoapp-frontend' asked for scope 'test_core_web_api_spa' that doesn't exist on the resource 'myportal_guid'.
Sorry for all the confusion but I've been trying everything and the code is getting messy. I'm almost to the point where I might need to start over again.
Modify your code as below
window.config = {
clientID: 'clientidof_web_client'
};
var scope = ["api://{clientidof_web_api}/.default"];
You can check the token by decoding it. The value of aud should be api://client_id_of_web_api
Update:
Have you added your api to your client app permission?
The problem was the configuration data for the Web API. When they say the ClientId what they really want is the value under the "expose an API" option where it says "Application ID URI". What I was putting in there was the guid for the Web Api application registration. Below is how it should look.
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "myportal.onmicrosoft.com",
"TenantId": "mytenant-guid",
"ClientId": "https://myportal.onmicrosoft.com/test_core_web_api_spa"
},

How can I use google api in chrome extension content script?

I am trying to list labels using Gmail api. I want to use Gmail api in content script. Following is my manifest.json file and content script file:
{
"name": "Append Test Text",
"description": "Add test123 to body",
"version": "1.0",
"permissions": ["activeTab"],
"content_scripts": [
{
"matches": ["https://mail.google.com/*"],
"js": ["jquery-3.4.1.min.js", "gmail.js", "content-script.js"],
"all_frames": true
}
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"browser_action": {
"default_title": "Append Test Text"
},
"manifest_version": 2
}
content-script.js:
// Client ID and API key from the Developer Console
var CLIENT_ID = "<CLIENT_ID>";
var API_KEY = "<API_KEY>";
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = [
"https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"
];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/gmail.readonly";
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
console.log("hello");
gapi.load("client:auth2", initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client
.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
})
.then(
function() {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
},
function(error) {
console.log(JSON.stringify(error, null, 2));
}
);
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
listLabels();
} else {
gapi.auth2.getAuthInstance().signIn();
}
}
/**
* Print all Labels in the authorized user's inbox. If no labels
* are found an appropriate message is printed.
*/
function listLabels() {
gapi.client.gmail.users.labels
.list({
userId: "me"
})
.then(function(response) {
var labels = response.result.labels;
console.log("Labels:");
if (labels && labels.length > 0) {
for (i = 0; i < labels.length; i++) {
var label = labels[i];
console.log(label.name);
}
} else {
console.log("No Labels found.");
}
});
}
var script = $(
'<script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === "complete") this.onload()"></script>'
);
$("body").append(script);
after running this there should at least be a "hello" in the console proving that the handleClientLoad() function is working. But nothing shows in the console.
Technically, Chrome won't allow you to do that. If you use content script to inject into a website then you can just send request only on that site, if you're trying to send a request into another site, Chrome will stop you due to CORS policy.
So to achieve it, you have to setup a background script which receive passed messages from your content script and then send request into Google API endpoint and then you can return the result into your content script via defined message channel. Here is how you can setup message passing in Chrome Extension.

#me called by anonymous error when using google plus api inside a gwt project

I'm using the google api javascript client to get information about the user profile inside a gwt project hosted in google app engine.
In localhost, the data is being retrieved correctly. I get a json with the google plus profile. When I deploy to appengine, the response is 401, "#me called by anonymous".
Here is my Code:
<script src="https://apis.google.com/js/client.js"></script>
<script type="text/javascript">
$(function() {
auth();
});
var API_KEY = "***************************************";
var CLIENT_ID = "************.apps.googleusercontent.com";
var scopes = 'https://www.googleapis.com/auth/plus.me';
function auth() {
var config = {
'client_id' : CLIENT_ID,
'scope' : scopes,
'key' : API_KEY,
};
gapi.client.load('plus', 'v1', function() {
api.client.setApiKey(API_KEY);
gapi.auth.authorize(config, function() {
var request = gapi.client.plus.people.get({
'userId' : 'me',
});
request.execute(function(resp) {
console.log(resp);
});
});
});
}
</script>
What i tried:
call to api.client.setApiKey at the begining.
create a new google api access with the google api console
update:
This is the complete response error message:
{
"error": {
"code": 401,
"message": "me called by anonymous",
"data": [
{
"domain": "global",
"reason": "authError",
"message": "me called by anonymous",
"locationType": "header",
"location": "Authorization"
}
]
},
"id": "gapiRpc"
}
There are other messages that may be related:
This is one of them:
Skipping duplicate osapi method definition chili.people.list on transport googleapis; others may exist, but suppressing warnings cb=gapi.loaded1 (línea 119)
Skipping duplicate osapi method definition pos.plusones.list on transport googleapis; others may exist, but suppressing warnings cb=gapi.loaded1 (línea 119)
Skipping duplicate osapi method definition chili.activities.list on transport googleapis; others may exist, but suppressing warnings cb=gapi.loaded1 (línea 119)
Skipping duplicate osapi method definition googleapis.newHttpRequest on transport googleapis; others may exist, but suppressing warnings
this is the other:
Invalid auth token. 1025***** vs 140186****
I could finally resolve the issue with the following settings or steps:
1) In the google apis console, I left the Redirect URIs section empty and completed the JavaScript origins section with the url of my site, repeating it with the https protocol:
JavaScript origins:
http://example.com
https://example.com
I put the script that loads the api before the end body tag:
<script src="https://apis.google.com/js/client.js"></script>
This script comes inside the body, before the api script:
<script type="text/javascript">
var API_KEY = "***************************************";
var CLIENT_ID = "************.apps.googleusercontent.com";
var scopes = 'https://www.googleapis.com/auth/plus.me';
function auth() {
var scopes = 'https://www.googleapis.com/auth/plus.me';
gapi.client.setApiKey(API_KEY);
window.setTimeout(checkAuth, 1000);
function checkAuth() {
gapi.auth.authorize({
client_id : CLIENT_ID,
scope : scopes,
immediate : false
}, handleAuthResult);
}
function handleAuthResult(authResult) {
if (authResult) {
makeApiCall();
} else {
checkAuth();
}
}
function makeApiCall() {
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId' : 'me'
});
request.execute(function(resp) {
$("#image").attr("src", resp.image.url);
});
});
}
}
</script>
Then I call the function auth() when the user clicks to see his picture.

Categories

Resources