Unable to query Google Search Console API using a Service Account - javascript

I need to retrieve some data from Google Search Console (Webmaster Tools) using a service account.
So far I've been able to retrieve an access_token for the service account which I need to append to the url of the request. The problem is that I can't find a way to do so, this is the code i'm using:
function retrieveSearchesByQuery(token)
{
gapi.client.webmasters.searchanalytics.query(
{
'access_token': token,
'siteUrl': 'http://www.WEBSITE.com',
'fields': 'responseAggregationType,rows',
'resource': {
'startDate': formatDate(cSDate),
'endDate': formatDate(cEDate),
'dimensions': [
'date'
]
}
})
.then(function(response) {
console.log(response);
})
.then(null, function(err) {
console.log(err);
});
}
This is the url called by the function:
https://content.googleapis.com/webmasters/v3/sites/http%3A%2F%2Fwww.WEBSITE.com/searchAnalytics/query?fields=responseAggregationType%2Crows&alt=json"
Instead it should be something like this:
https://content.googleapis.com/webmasters/v3/sites/http%3A%2F%2Fwww.WEBSITE.com/searchAnalytics/query?fields=responseAggregationType%2Crows&alt=json&access_token=XXX"
The gapi.client.webmasters.searchanalytics.query doesn't recognize 'access_token' as a valid key thus it doesn't append it to the url and that's why I get a 401 Unauthorized as response.
If I use 'key' instead of 'access_token' the parameter gets appended to the url but 'key' is used for OAuth2 authentication so the service account token I pass is not valid.
Does anyone have a solution or a workaround for this?

If your application requests private data, the request must be authorized by an authenticated user who has access to that data. As specified in the documentation of the Search Console API, your application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported.
If you application is correctly configured, when using the Google API, an authenticated request looks exactly like an unauthenticated request. As stated in the documentation, if the application has received an OAuth 2.0 token, the JavaScript client library includes it in the request automatically.
You're mentioning that you have retrieved an access_token, if correctly received, the API client will automatically send this token for you, you don't have to append it yourself.
A very basic workflow to authenticate and once authenticated, send a request would looks like the following code. The Search Console API can use the following scopes: https://www.googleapis.com/auth/webmasters and https://www.googleapis.com/auth/webmasters.readonly.
var clientId = 'YOUR CLIENT ID';
var apiKey = 'YOUR API KEY';
var scopes = 'https://www.googleapis.com/auth/webmasters';
function auth() {
// Set the API key.
gapi.client.setApiKey(apiKey);
// Start the auth process using our client ID & the required scopes.
gapi.auth2.init({
client_id: clientId,
scope: scopes
})
.then(function () {
// We're authenticated, let's go...
// Load the webmasters API, then query the API
gapi.client.load('webmasters', 'v3')
.then(retrieveSearchesByQuery);
});
}
// Load the API client and auth library
gapi.load('client:auth2', auth);
At this point, your retrieveSearchesByQuery function will need to be modified since it doesn't need to get a token by argument anymore in order to pass it in the query. The JavaScript client library should include it in the request automatically.
You can also use the API Explorer to check what parameters are supported for a specific query and check the associated request.
If you need to use an externally generated access token, which should be the case with a Service Account, you need to use the gapi.auth.setToken method to sets the OAuth 2.0 token object yourself for the application:
gapi.auth.setToken(token_Object);

Related

Refresh token for Google OAuth 2.0

I have an application that uses Google APIs in some places, and I want to avoid having the user login every time. Currently, I only receive a Google access token in the response, not a refresh token. How can I obtain the refresh token?
This is the function I use to when the user click to login with google:
authenticate() {
const client = google.accounts.oauth2.initTokenClient({
client_id: 'MY_CLIENT_ID',
scope: [
"All_NECESSARY_SCOPES",
].join(" "),
callback: (res) => {
this.accessToken = res.access_token
this.loadClient()
}
})
client.requestAccessToken()
},
It works for getting the access token. And I need the refresh token, Please Help Me :)
Client side JavaScript does not return a refresh token. It would be a security risk.
If you want a refresh token you need to use a server sided language like Node.js

setting js azure app service custom login authentication

I started implementing 2 years ago my custom authentication in azure mobile service with node.js to use it in my jquery/cordova appery.io app. I have a database with users, passwords, etc and a login api in node.js backend that generates a valid jwt like this:
http://www.thejoyofcode.com/Exploring_custom_identity_in_Mobile_Services_Day_12_.aspx
http://chrisrisner.com/Version-1-of-the-Mobile-Services-JWT-token-has-been-deprecated
But now i have been migrated to azure app service and don´t know how to implement custom authetication with javascript.
At the examples above:
"iss":"urn:microsoft:windows-azure:zumo",
"ver":2,
"aud":aud,
But i have read that "aud" and "iss" must be my azure website and "sub" my own userId, to generate a valid jwt in my custom auth to use it in azure. Is it right?
https://shellmonger.com/2016/04/08/30-days-of-zumo-v2-azure-mobile-apps-day-5-custom-authentication/
The important thing is the token. There are some requirements for using 3rd party tokens with an Azure Mobile App:
It must follow the Json Web Token format
The user Id must be in the subject (sub) field
The audience (aud) and issuer (iss) must be known and configured
I do a call to my login API with ajax post and obtain a valid JWT token (http://jwt.io), but i don´t know the correct process to login and use azure services because i don´t know the correct way to use it on my app. I have changed MobileServices.Web.min.js to azure-mobile-apps-client.js in the app.
https://github.com/Azure/azure-mobile-apps-js-client
Can i use the jwt token created in azure node.js or exchange it for a session token and use client.login() method by JS SDK?
EDIT:
I see the light again adding to ajax POST
headers: {'X-ZUMO-AUTH': usuarioToken},
So my "authenticated users only" api works again with the old MobileServices.Web.min.js! It also works perfect with invokeApi method:
var mobileClient = new WindowsAzure.MobileServiceClient(urlApp,keyApp);
mobileClient.currentUser = {
userId: myCustomUserId,
mobileServiceAuthenticationToken: myCustomToken
};
mobileClient
.invokeApi('data', {
method: 'POST',
headers: {'X-ZUMO-AUTH': myCustomToken},
body: JSON.stringify(theData)
}) //end invokeApi
.done(
function (response) {
alert(response);
},
function (error) {
alert("error"));
}
); //end done
The mobileClient generated contains this data:
mobileClient= {"applicationUrl":"https://xxx.azure-mobile.net/","applicationKey":"hGhzxxx","version":"ZUMO/1.2 (lang=Web; os=--; os_version=--; arch=--; version=1.2.21003.0)","currentUser":{"userId":"Custom:25F600BB-xxxx-xxxx-xxxx-8329BCCF31D2","mobileServiceAuthenticationToken":"ey__rest of jwt token"},"_serviceFilter":null,"_login":{"_loginState":{"inProcess":false,"cancelCallback":null},"ignoreFilters":true},"push":{"_apns":null,"_gcm":null,"_registrationManager":null}}
I will try again wiht the new azure-mobile-apps-client.js
Any comment will be welcome

Skype Web SDK - Maintain a user session

I am using Skype Web SDK to get a user's contact list in the following manner.
Skype.initialize({
apiKey: 'a42fcebd-5b43-4b89-a065-74450fb91255',
}, function (api) {
var Application = api.application;
var client = new Application();
client.signInManager.signIn({
username: sip,
password: pwd
})
This works fine when I provide the username(sip) and password. However, when I reload the page, I have to provide the credentials again because the app re-initializes. Is there a way to maintain the user's sessions for a while after the initial login so that the page refreshes wouldn't need ask for credentials again?
I have looked through the samples and docuementation that Microsoft has and couldn't find a way. I've also tried to store the client object in the localStorage after the initialization and sign in, but when I tried to reuse the object from localStorage to get the contact list, it did not work.
http://officedev.github.io/skype-docs/Skype/WebSDK/model/api/interfaces/jcafe.signinmanager.html#signin last example explains that you can store oauth token and use it as unexpired token.
To connect to an existing app's event channel, specify id of that app:
sm.signIn({
username: "user1#company.com",
password: "password1",
id: "273867-234235-45346345634-345"
});
To sign in to Skype for Business Online using OAuth while handling the
logic of retrieving OAuth tokens yourself:
sm.signIn({
client_id: '123-456',
origins: [ 'https://webdir.online.lync.com/AutoDiscover/AutoDiscoverservice.svc/root' ],
cors: true,
get_oauth_token: function(resource) {
// Return a valid unexpired token for the specified resource if you already have one.
// Else, return a promise and resolve it once you have obtained a token.
return 'Bearer eyJ0e...';
}
});

API Gateway authentication with Cognito Federated Identities

I want to use Cognito Federated Entity (allowing signin through Google etc), to allow access to API Gateway for a web javascript application.
I managed to get the Cognito's sessionToken through signing-in with Google but I'm stuck on the API Gateway configuration for enabling the session token.
Is there a good tutorial for this entire Federated Entity authentication workflow?
Thanks!
Since you want to invoke APIs via authenticated Cognito identity, first
Amend the auth role of the identitypool to have api execute policy, you could just attach the managed policy "AmazonAPIGatewayInvokeFullAccess" to the respective role
In API gateway under respective method request, add Authorization as
"AWS_IAM"
You need to sign the request while using "IAM" auth, explained here https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html
Instead of #3, you could generate and download the SDK from the stage panel of your API gateway, and make a call to the api via sdk.
Once you obtain the cognito session, you could make a call using the sdk like below
var apigClient = apigClientFactory.newClient({
accessKey: AWSCognito.config.credentials.accessKeyId,
secretKey: AWSCognito.config.credentials.secretAccessKey,
sessionToken: AWSCognito.config.credentials.sessionToken
});
var params = {
// This is where any modeled request parameters should be added.
// The key is the parameter name, as it is defined in the API in API Gateway.
};
var body = {};
var additionalParams = {
// If there are any unmodeled query parameters or headers that must be
// sent with the request, add them here.
headers: {
'Content-Type': 'application/json'
},
queryParams: {}
};
apigClient.<resource><Method>(params, body, additionalParams)
.then(function(result) {
//
}).catch(function(err) {
//
});

Can an access token returned by Facebook to the Javascript SDK work server-side with the PHP SDK?

I'm building a website that makes use of Facebook connect. I'm authenticating users client-side with the javascript SDK and calling an AJAX method on my server every time a user logs in to check if the user is known to my app, and if the user is new to store their FBID in my database to register them as a new user.
My question is: Can the access token returned by Facebook to the Javascript SDK be used server-side (with the PHP SDK for example)? Can I send the access token string to the server via an AJAX call, store it in my database (along with a timestamp so I know how long it's valid for) and then use it to make calls to the graph API server-side? Is this even a logical thing to do?
Yes, this should work. Look at this question: How to properly handle session and access token with Facebook PHP SDK 3.0?
This is a workaround for the old JS and new PHP SDK. In my app I send the access token generated by the JS SDK via a form to my PHP. I have no doubts that this also works by sending the access token via ajax!
Using Jquery:
//Set an error message
var oops = ("Put your something went wrong message here.");
//Function to post the data to the server
function save(uid, accessToken){
$.post("../foo/bar", { uid: uid, access_token: accessToken, etc, etc }, function(data){
alert("Successfully connected to Facebook.");
location.reload();
}, "text");
}
function handler(x){
if (x.authResponse){
var token = x.authResponse.accessToken;
var uid = x.authResponse.id;
FB.api("/me/accounts", {access_token: token},
function(response){
if(response.data.length == 0) {
//Regular facebook user with one account (profile)
save(uid, token);
}else{
//Handle multiple accounts (if you want access to pages, groups, etc)
}
});
}else{
alert(oops);
}
}
FB.login(handler, {scope: 'The list of permissions you are requesting goes here'});
Any improvement suggestions are always appreciated.

Categories