OAuth 2.0 Authentication screen stays open - javascript

Quick question that has be baffled.
I'm following the examples from I/O '12 ( link ) and I got it working but for some reason after I grant access, the window goes to a white screen, the title says "Connecting..." and stays there. There are no errors in the console, and I'm good to go as far as the OAuth authentication is concerned.
I want to point out that I'm doing this inside a Chrome extension's popup using a page action. I don't know if that makes any difference.
The demo of that sample works great so I'm thinking it has something to do with being inside a chrome extension. I just can't figure out what it could be. demo
The code I'm using is pretty much identical to the sample:
js/oauth/oauth.js:
var clientId = '[MY_CLIENTID]';
var apiKey = '[MY_API_KEY]';
var scopes = 'https://www.googleapis.com/auth/plus.me';
// Use a button to handle authentication the first time.
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult(authResult) {
var authorizeButton = document.getElementById('authorize-button');
var flows = document.getElementById('flows');
var welcome = document.getElementById('welcome');
if (authResult && !authResult.error) {
flows.style.display = 'none';
welcome.style.display = '';
makeApiCall();
} else {
flows.style.display = '';
welcome.style.display = 'none';
authorizeButton.onclick = handleAuthClick;
}
}
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
return false;
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp) {
var heading = document.createElement('p');
var image = document.createElement('img');
image.src = resp.image.url;
var welcometext = document.createTextNode("Welcome ");
var welcometextend = document.createTextNode(", you are now logged in!");
heading.appendChild(welcometext);
heading.appendChild(document.createTextNode(resp.displayName));
heading.appendChild(welcometextend);
document.getElementById('content').appendChild(heading);
document.getElementById('avatar').appendChild(image);
});
});
}
popup.html:
<html>
<head>
<script src="js/oauth/oauth.js"></script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body style="width: 500px">
<div id="flows" style="display: none;" >
<h2>Please log in before starting</h2>
<button id="authorize-button">Log in</button>
</div>
<div id="welcome" style="display: none;">
<div id="avatar"></div>
<div id="content"></div>
</div>
</body>
</html>
sdlkfad
This is what it looks like:

Related

How to get id_token from the response generated after user sign up using gmail api?

I am using Gmail API for user signup to my application. For user verification, I would require id_token generated after user signup. I am logging following object but can't see id_token in there.
access_token:"xx"
authuser:"xx"
client_id:"xx"
cookie_policy:"xx"
expires_at:"xx"
expires_in:"xx"
issued_at:"xx"
login_hint:"xx"
response_type:"xx"
scope:"xx"
session_state:"xx"
status:"xx",
token_type: "xx"
following is the code
const API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
var clientId = 'xxxxx-xxxx.apps.googleusercontent.com';
const scopes =
'https://www.googleapis.com/auth/plus.login '+'https://www.googleapis.com/auth/gmail.readonly '+
'https://www.googleapis.com/auth/gmail.send';
const script = document.createElement("script");
script.src = "https://apis.google.com/js/client.js";
script.async = true
script.onload = () => {
window.gapi.load('auth2', () => {
window.gapi.client.setApiKey(API_KEY);
window.setTimeout(checkAuth, 1);
});
}
document.body.appendChild(script)
function checkAuth() {
gapi.auth2.init({
client_id: clientId,
scope: scopes,
immediate: true
}, handleAuthResult);
}
function handleAuthClick() {
gapi.auth2.init({
client_id: clientId,
scope: scopes,
immediate: false
}, handleAuthResult);
return false;
}
function handleAuthResult(authResult) {
if(authResult && !authResult.error) {
loadGmailApi();
console.log(authResult)
} else {
$('#authorize-button').on('click', function(){
handleAuthClick();
});
}
}
function loadGmailApi() {
gapi.client.load('gmail', 'v1', () => console.log('loaded'));
}
Logging authResult gives me above mentioned output object. Can you please check what am I missing and how can I get that id_token. I am using this link to send emails using Gmail API: https://www.sitepoint.com/mastering-your-inbox-with-gmail-javascript-api/
You are not properly logging in your client Js start
<!DOCTYPE html>
<html>
<head>
<title>Gmail API Quickstart</title>
<meta charset='utf-8' />
</head>
<body>
<p>Gmail API Quickstart</p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>
<pre id="content"></pre>
<script type="text/javascript">
// Client ID and API key from the Developer Console
var CLIENT_ID = '<YOUR_CLIENT_ID>';
// 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';
var authorizeButton = document.getElementById('authorize-button');
var signoutButton = document.getElementById('signout-button');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
clientId: CLIENT_ID,
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());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
});
}
/**
* 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) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
listLabels();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* 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;
appendPre('Labels:');
if (labels && labels.length > 0) {
for (i = 0; i < labels.length; i++) {
var label = labels[i];
appendPre(label.name)
}
} else {
appendPre('No Labels found.');
}
});
}
</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>
</html>
For an id_token to be returned, you need to kickstart and OpenID Connect flow, which is done by adding the scope openid to the list of scopes in your authorization request.

TypeError: gapi.client is undefined error while downloading files from file picker

I have implemented a google file picker in HTML and JS. I have created a client credentials and in the verge of downloading the files from file picker. My code is
<!DOTYPE html>
<html>
<head>
<title>My website</title>
<script type="text/javascript">
// The Browser API key obtained from the Google API Console.
var developerKey = '############################';
// The Client ID obtained from the Google API Console. Replace with your own Client ID.
var clientId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
// Scope to use to access user's photos.
var scope = 'https://www.googleapis.com/auth/drive';
var appId = "1255s8a2s";
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth2', onAuthApiLoad);
gapi.load('picker', onPickerApiLoad);
gapi.client.load('drive', 'v2',handleClientLoad);
}
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(onAuthApiLoad,1);
}
function onAuthApiLoad() {
var authBtn = document.getElementById('auth');
authBtn.disabled = false;
authBtn.addEventListener('click', function() {
gapi.auth2.authorize({
client_id: clientId,
scope: scope
}, handleAuthResult);
});
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.NAV_HIDDEN).
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
setOAuthToken(oauthToken).
setAppId(appId).
addView(view).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
var ids=[];
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var ln = data[google.picker.Response.DOCUMENTS];
for(i=0;i<ln.length;i++) {
ids[i] = data.docs[i].id;
gapi.client.drive.files.get({'fileId': ids[1]});
}
}
}
</script>
</head>
<body>
<h1> Welcome to detect the colours of your image </h1>
<p> Please upload required images. Let us detect what wonderful colours do your images have</p>
<form id="upload-form" action="{{ url_for('upload') }}" method = "POST" enctype="multipart/form-data">
<input type = "file" name="file" accept="image/*" multiple>
<input type="submit" value="upload">
</form>
<form method = "POST" action="/gdrive">
<button type="button" id="auth">upload from google</button>
</form>
<div id="result"></div>
<!-- The Google API Loader script. -->
<script src="https://apis.google.com/js/platform.js?onload=init" async defer></script>
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
</body>
</html>
After reading google drive javascript api gapi.client.drive.files undefined, I decided to add gapi.client.load('drive', 'v2', callback); in my code. However the result remains the same. I could not initialize the gapi.client, The drive api is enabled. I am new to Javascript, Can anyone please help me download the files using file ids. The File ids are stored in ids[] array in the code.
Thank you for trying to help me out

Google Contacts to Dropdown List

I'm wondering if anyone can help with this. I am using the following code to pull my google contacts using OAuth and it's working fine so far, I get a response in the console log with XML from google that seems very complicated to read to be honest.
My end goal is to be able to populate a HTML form drop down list with the names of contacts from my address book, and attribute the phone number for that contact as a value for the chosen name.
Here's the code, please let me know if you have any ideas!
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
</head>
<body>
<script type="text/javascript">
var clientId = 'ID_HERE';
var apiKey = 'KEY_HERE';
var scopes = 'https://www.googleapis.com/auth/contacts.readonly';
$(document).on("click",".googleContactsButton", function(){
gapi.client.setApiKey(apiKey);
window.setTimeout(authorize);
});
function authorize() {
gapi.auth.authorize(
{
client_id: clientId,
scope: scopes,
immediate: false
},
handleAuthorization
);
}
function handleAuthorization(authorizationResult) {
if (authorizationResult && !authorizationResult.error) {
$.get(
"https://www.google.com/m8/feeds/contacts/default/thin?alt=json&access_token="
+ authorizationResult.access_token + "&max-results=500&v=3.0",
function(response){
//process the response here
console.log(response);
}
);
}
}
</script>
<script src="https://apis.google.com/js/client.js"></script>
<button class="googleContactsButton">Get my contacts</button>
</body>
</html>
EDIT
So, I've played around for a bit, and this is what I've got so far, which works fine, I get the results listed in as name on one line, then number on the next, then name, and so on..
Problems so far are as follows.
This only returns a limited number of contacts, I believe there's a limit on the response from the API which is 200 or something (I think), how would I go about having it display ALL the contacts that are there?
Also I'm still trying to get it to display in a select box format, allowing me to choose a name, and it would pass the number linked to that name to the form.
Any ideas?
<!DOCTYPE html>
<html>
<head>
<title>People API Quickstart</title>
<meta charset='utf-8' />
</head>
<body>
<p>People API Quickstart</p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>
<pre id="content"></pre>
<script type="text/javascript">
// Client ID and API key from the Developer Console
var CLIENT_ID = 'CLIENT ID.apps.googleusercontent.com';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/people/v1/rest"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/contacts.readonly";
var authorizeButton = document.getElementById('authorize-button');
var signoutButton = document.getElementById('signout-button');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
clientId: CLIENT_ID,
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());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
});
}
/**
* 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) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
listConnectionNames();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* Print the display name if available for 10 connections.
*/
function listConnectionNames() {
gapi.client.people.people.connections.list({
'resourceName': 'people/me',
'pageSize': 2000,
'personFields': 'names,phoneNumbers',
}).then(function(response) {
console.log(response)
var connections = response.result.connections;
appendPre('<select>');
if (connections.length > 0) {
for (i = 0; i < connections.length; i++) {
var person = connections[i];
if (person.names && person.names.length > 0) {
appendPre(person.names[0].displayName)
appendPre(person.phoneNumbers[0].value)
} else {
appendPre("No display name found for connection.");
}
}
} else {
appendPre('No upcoming events found.');
}
});
}
</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>
</html>
Accessing the Contacts
When you receive the response, the contacts are located under response.feed.entry, which is an array of contacts. Let's save those under var contacts = response.feed.entry. And as an example for what follows, let's take the contact Jimmy : var jimmy = contacts[0].
You have several attributes that you can access, like :
Email : jimmy.gd$email[0].address. ( there can be more emails )
Name : jimmy.title.$t.
Phone : jimmy.gd$phoneNumber[0].$t.
Address : jimmy.gd$postalAddress[0].$t.
Last update made : jimmy.updated.$t.
Warning : If the field is not set, it will be undefined. You have to first verify that it exists, like so :
// Standard way
var name;
if (jimmy.title != undefined) name = jimmy.title.$t
else name = "?? well too bad ??";
// The ninja way
var name = jimmy.title ? jimmy.title.$t : null;
Also
Change your get url to https://www.google.com/m8/feeds/contacts/default/**full**/... as you will get more information on your contacts.
Populating a drop-down
For simplicity, you could use a <select> tag and insert the contacts as <option> tags in it. Else, you can also use libraries like bootstrap that has cool drop-downs menus.
If your code still doesn't work...
Try this code :
<html>
<head>
<script src="https://apis.google.com/js/client.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
function auth() {
var config = {
'client_id': 'OAUTH_CLIENT_ID',
'scope': 'https://www.google.com/m8/feeds'
};
gapi.auth.authorize(config, function() {
fetch(gapi.auth.getToken());
});
}
function fetch(token) {
$.ajax({
url: 'https://www.google.com/m8/feeds/contacts/default/full?alt=json',
dataType: 'jsonp',
data: token
}).done(function(data) {
console.log(JSON.stringify(data));
});
}
</script>
</head>
<body>
<button onclick="auth();">GET CONTACTS FEED</button>
</body>
</html>
Source

Google Calendar API javascript Error:Origin Mismatch

I'm working on a simple javascript code I found here: http://googleappsdeveloper.blogspot.com/2011/12/using-new-js-library-to-unlock-power-of.html
It basically acquires authentication to a google Calendar and retrieves the list of events contained in it. I have registered my web application and obtained a client ID and API Key.
I'm facing this error: "Error: Origin mismatch", I'm running the javascript locally using localhost and I set my homepage in the google application registration to localhost as well.
any help would be immensely appreciated.
the code:
<html>
<body>
<div id='content'>
<h1>Events</h1>
<ul id='events'></ul>
</div>
<a href='#' id='authorize-button' onclick='handleAuthClick();'>Login</a>
<script>
var clientId = '506979856128.apps.googleusercontent.com';
var apiKey = 'AIzaSyAGbQAZQU0YNL8hK5EU69exIg7_sOg3JoA';
var scopes = 'https://www.googleapis.com/auth/calendar';
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
checkAuth();
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true},
handleAuthResult);
}
function handleAuthResult(authResult) {
var authorizeButton = document.getElementById('authorize-button');
if (authResult) {
authorizeButton.style.visibility = 'hidden';
makeApiCall();
} else {
authorizeButton.style.visibility = '';
authorizeButton.onclick = handleAuthClick;
}
}
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: clientId, scope: scopes, immediate: false},
handleAuthResult);
return false;
}
function makeApiCall() {
gapi.client.load('calendar', 'v3', function() {
var request = gapi.client.calendar.events.list({
'calendarId': 'primary'
});
request.execute(function(resp) {
for (var i = 0; i < resp.items.length; i++) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(resp.items[i].summary));
document.getElementById('events').appendChild(li);
}
});
});
}
</script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"> </script>
</body>
</html>
I got the same error origin mismatch today.after bit of search i got the reason.
While creating the Google Api Access,we have to specify Authorized Redirect URIs and Authorized Redirect URIs.
Now if you call the Login from URIs other than specified in Authorized Redirect URIs, error:Unknown Origin is thrown
FYI:I have seen that you are running the javascript locally using localhost.
It means that You have not added localhost uri to Authorized Redirect URIs.
But Don't waste your time doing that.Authorized Redirect URIs will not accept localhost uri.It's due to Chrome's same origin policy.and If you run chrome with the disable-web-security flag, it'll work locally too.
The problem of origin mismatch can be solved by taking care for Redirect URIs and Javascript Origins when creating Client ID in Google Developers Console.
The Javascript Origins should not end with /.
Example: http://example.com/ --> The correct format will be http://example.com.

Google Calendar API Javascript Quickadd

Trying to allow a user to authenticate and quickadd an event using the Google calendar API v3 with javascript. I dont see the authenticate button. I am very inexperienced with coding.
Console:
Uncaught SyntaxError: Unexpected token } test.html:47
Uncaught TypeError: Cannot read property 'qainput' of undefined test.html:62
onload test.html:62
html file:
<html>
<head>
<meta charset='utf-8' />
<style>
#info {
border: 0px solid black;
padding: 0.25em;
margin: 0.5em 0;
}
</style>
<script type="text/javascript">
var apiKey = 'AIzaSyDcbjOvAT85hCdVrjgUAqylf_QtxE2Gx60';
var clientId = '202852486259.apps.googleusercontent.com';
var scopes = 'https://www.googleapis.com/auth/calendar';
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult(authResult) {
var authorizeButton = document.getElementById('authorize-button');
if (authResult) {
authorizeButton.style.visibility = 'hidden';
makeApiCall();
} else {
authorizeButton.style.visibility = '';
authorizeButton.onclick = handleAuthClick;
}
}
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
return false;
}
function makeRpcRequest() {
var qatext = document.qaform.qainput.value;
var request = gapi.client.calendar.events.quick_add({
'calendarId': 'primary',
'text': +qatext+
});
request.execute(writeResponse);
}
function writeResponse(response) {
console.log(response);
var name = response.summary;
var infoDiv = document.getElementById('info');
var infoMsg = document.createElement('P');
infoMsg.appendChild(document.createTextNode(+ name' sucessfully created!'));
infoDiv.appendChild(infoMsg);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body onload="document.qaform.qainput.focus();">
<button id="authorize-button" style="visibility: hidden">Authorize to Use QuickAdd</button>
<form id="qaform">
<input placeholder='QuickAdd' name='qainput' />
<button id="rpc" onclick="makeRpcRequest();">Add</button>
</form>
<div id="info"></div>
</body>
</html>
As its been a few weeks you've probably found your answer but I was having the same issue recently starting with basically the same code that you're using. I had simply not activated google calendar under "services" in the google console. If all of the console settings aren't correct, the "authorize" button remains hidden(it is hidden by default). Once all the settings are correct and the script is communicating properly with the api, the authorize button becomes visible and you can then add the event and write the response by clicking the button.

Categories

Resources