Is it possible to get an identifier token with the App App attribute Appity Api attribute?

I cannot get the id_token of the user ( https://developers.google.com/accounts/docs/CrossClientAuth ) from the Chrome api id ( https://developer.chrome.com/apps/identity ).

I can get access_token using the chrome authentication pattern when the oauth section is in the manifest:

"oauth2": { "client_id": "<chrome-app-client-id>.apps.googleusercontent.com", "scopes": ["https://www.googleapis.com/auth/plus.login"] } 

But when I try to get id_token in the same way as I get it on my Android client, get an error:

"OAuth2 request error: the service responded with an error: 'invalid area: {0}'"}

Now the manifest section:

 "oauth2": { "client_id": "<chrome-app-client-id>.apps.googleusercontent.com", "scopes": ["audience:server:client_id:<app-engine-client-id>.apps.googleusercontent.com"] } 

On Android, I get id_token by passing the same scope string to android.gms.auth.GoogleAuthUtil.getToken (), but I can't get it to work with the chrome id api.

Is it possible to get id_token with Chrome App Indentity Api? If not, how can I get id_token for my Chrome app?

Thank you for your help!

+7
google-chrome-extension google-chrome-app token google-openid
source share
2 answers

Yesterday I ran into the same problem, and since I found a solution, I could also share it, since it was not so obvious. As far as I know, Google does not provide a direct and documented way to do this, but you can use the chrome.identity.launchWebAuthFlow() function.

You must first create the Web application credentials in the Google console and add the following URL as a valid Authorized redirect URI : https://<EXTENSION_OR_APP_ID>.chromiumapp.org . The URI should not exist, chrome will simply intercept the redirect to this URL and call your callback function later.

manifest.json

 { "manifest_version": 2, "name": "name", "description": "description", "version": "0.0.0.1", "background": { "scripts": ["background.js"] }, "permissions": [ "identity" ], "oauth2": { "client_id": "<CLIENT_ID>.apps.googleusercontent.com", "scopes": [ "openid", "email", "profile" ] } } 

background.js

 // Using chrome.identity var manifest = chrome.runtime.getManifest(); var clientId = encodeURIComponent(manifest.oauth2.client_id); var scopes = encodeURIComponent(manifest.oauth2.scopes.join(' ')); var redirectUri = encodeURIComponent('https://' + chrome.runtime.id + '.chromiumapp.org'); var url = 'https://accounts.google.com/o/oauth2/auth' + '?client_id=' + clientId + '&response_type=id_token' + '&access_type=offline' + '&redirect_uri=' + redirectUri + '&scope=' + scopes; chrome.identity.launchWebAuthFlow( { 'url': url, 'interactive':true }, function(redirectedTo) { if (chrome.runtime.lastError) { // Example: Authorization page could not be loaded. console.log(chrome.runtime.lastError.message); } else { var response = redirectedTo.split('#', 2)[1]; // Example: id_token=<YOUR_BELOVED_ID_TOKEN>&authuser=0&hd=<SOME.DOMAIN.PL>&session_state=<SESSION_SATE>&prompt=<PROMPT> console.log(response); } } ); 

The Google OAuth2 API documentation (for OpenID Connect) can be found here: https://developers.google.com/identity/protocols/OpenIDConnect#authenticationuriparameters

PS: If you do not need the oauth2 section in the manifest. You can safely omit it and provide identifiers and areas only in code.

EDIT: For those who wish you do not need an authentication API. You can even access the token using a little trick with the tabs API. The code is a little longer, but you have better error messages and management. Keep in mind that in the following example, you need to create Chrome App credentials.

manifest.json

 { "manifest_version": 2, "name": "name", "description": "description", "version": "0.0.0.1", "background": { "scripts": ["background.js"] }, "permissions": [ "tabs" ], "oauth2": { "client_id": "<CLIENT_ID>.apps.googleusercontent.com", "scopes": [ "openid", "email", "profile" ] } } 

background.js

 // Using chrome.tabs var manifest = chrome.runtime.getManifest(); var clientId = encodeURIComponent(manifest.oauth2.client_id); var scopes = encodeURIComponent(manifest.oauth2.scopes.join(' ')); var redirectUri = encodeURIComponent('urn:ietf:wg:oauth:2.0:oob:auto'); var url = 'https://accounts.google.com/o/oauth2/auth' + '?client_id=' + clientId + '&response_type=id_token' + '&access_type=offline' + '&redirect_uri=' + redirectUri + '&scope=' + scopes; var RESULT_PREFIX = ['Success', 'Denied', 'Error']; chrome.tabs.create({'url': 'about:blank'}, function(authenticationTab) { chrome.tabs.onUpdated.addListener(function googleAuthorizationHook(tabId, changeInfo, tab) { if (tabId === authenticationTab.id) { var titleParts = tab.title.split(' ', 2); var result = titleParts[0]; if (titleParts.length == 2 && RESULT_PREFIX.indexOf(result) >= 0) { chrome.tabs.onUpdated.removeListener(googleAuthorizationHook); chrome.tabs.remove(tabId); var response = titleParts[1]; switch (result) { case 'Success': // Example: id_token=<YOUR_BELOVED_ID_TOKEN>&authuser=0&hd=<SOME.DOMAIN.PL>&session_state=<SESSION_SATE>&prompt=<PROMPT> console.log(response); break; case 'Denied': // Example: error_subtype=access_denied&error=immediate_failed console.log(response); break; case 'Error': // Example: 400 (OAuth2 Error)!!1 console.log(response); break; } } } }); chrome.tabs.update(authenticationTab.id, {'url': url}); }); 
+5
source share

First, I assume that in your manifest.json snippet you do not mean that your client_id is literally "<chrome-app-client-id>.apps.googleusercontent.com . It should be something like 9414861317621.apps.googleusercontent.com is something you received from the Developer Console, or any other Google site that you used to register the application.

Assuming this is all correct, and you have client_id privileges, and the scope on the right, you get what is called the OAuth2 access token, with a call to chrome.identity.getAuthToken . Since you are not showing us any JavaScript code, I cannot say this is what you are doing. The access token you receive must be saved for later use when calling the API function. For example:

 var access_token; chrome.identity.getAuthToken( { 'interactive': true }, function(token) { access_token = token; // do something if you like to indicate // that the app is authorized } ); 

Then, when you call the API call, you provide this access token, for example:

 var url = 'https://www.googleapis.com/' + method; Ajax.ajaxSend(url, "json", function (status, response) { if (response && response.error && response.error.message) errorCallback(response.error.message); else if (status == 200) successCallback(response); else errorCallback('Result code: ' + status); }, function (e) { if (errorCallback) errorCallback('Communication error'); }, { Authorization: 'Bearer ' + access_token } ); 

Ajax.ajaxSend is my own function:

 var Ajax = (function () { var api = { ajaxSend: function (url, responseType, successCallback, errorCallback, headers) { var req = new XMLHttpRequest(); req.onload = function (e) { successCallback(req.status, req.response); }; req.onerror = errorCallback; req.responseType = responseType ? responseType : "text"; req.open("get", url); if (headers) for (var v in headers) req.setRequestHeader(v, headers[v]); req.send(); } }; return api; })(); 

Other undefined functions are also what you expect. The third argument to Ajax.ajaxSend is the header to send. (Sorry, I don’t have time to develop stand-alone code just for this answer.)

I hope this is helpful.

-one
source share

All Articles