Added an example using the identity API (#180)

* Added an example using the identity API

* Updated with review comment fixes
This commit is contained in:
wbamberg
2017-02-16 12:02:10 -08:00
committed by GitHub
parent 39cd28eb2b
commit 4474a6bd4b
10 changed files with 214 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
const REDIRECT_URL = browser.identity.getRedirectURL();
const CLIENT_ID = "YOUR-CLIENT-ID";
const SCOPES = ["openid", "email", "profile"];
const AUTH_URL =
`https://accounts.google.com/o/oauth2/auth
?client_id=${CLIENT_ID}
&response_type=token
&redirect_uri=${encodeURIComponent(REDIRECT_URL)}
&scope=${encodeURIComponent(SCOPES.join(' '))}`;
const VALIDATION_BASE_URL="https://www.googleapis.com/oauth2/v3/tokeninfo";
function extractAccessToken(redirectUri) {
let m = redirectUri.match(/[#\?](.*)/);
if (!m || m.length < 1)
return null;
let params = new URLSearchParams(m[1].split("#")[0]);
return params.get("access_token");
}
/**
Validate the token contained in redirectURL.
This follows essentially the process here:
https://developers.google.com/identity/protocols/OAuth2UserAgent#tokeninfo-validation
- make a GET request to the validation URL, including the access token
- if the response is 200, and contains an "aud" property, and that property
matches the clientID, then the response is valid
- otherwise it is not valid
Note that the Google page talks about an "audience" property, but in fact
it seems to be "aud".
*/
function validate(redirectURL) {
const accessToken = extractAccessToken(redirectURL);
if (!accessToken) {
throw "Authorization failure";
}
const validationURL = `${VALIDATION_BASE_URL}?access_token=${accessToken}`;
const validationRequest = new Request(validationURL, {
method: "GET"
});
function checkResponse(response) {
return new Promise((resolve, reject) => {
if (response.status != 200) {
reject("Token validation error");
}
response.json().then((json) => {
if (json.aud && (json.aud === CLIENT_ID)) {
resolve(accessToken);
} else {
reject("Token validation error");
}
});
});
}
return fetch(validationRequest).then(checkResponse);
}
/**
Authenticate and authorize using browser.identity.launchWebAuthFlow().
If successful, this resolves with a redirectURL string that contains
an access token.
*/
function authorize() {
return browser.identity.launchWebAuthFlow({
interactive: true,
url: AUTH_URL
});
}
function getAccessToken() {
return authorize().then(validate);
}
+23
View File
@@ -0,0 +1,23 @@
function notifyUser(user) {
browser.notifications.create({
"type": "basic",
"title": "Google info",
"message": `Hi ${user.name}`
});}
function logError(error) {
console.error(`Error: ${error}`);
}
/**
When the button's clicked:
- get an access token using the identity API
- use it to get the user's info
- show a notification containing some of it
*/
browser.browserAction.onClicked.addListener(() => {
getAccessToken()
.then(getUserInfo)
.then(notifyUser)
.catch(logError);
});
+22
View File
@@ -0,0 +1,22 @@
/**
Fetch the user's info, passing in the access token in the Authorization
HTTP request header.
*/
function getUserInfo(accessToken) {
const requestURL = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
const requestHeaders = new Headers();
requestHeaders.append('Authorization', 'Bearer ' + accessToken);
const driveRequest = new Request(requestURL, {
method: "GET",
headers: requestHeaders
});
return fetch(driveRequest).then((response) => {
if (response.status === 200) {
return response.json();
} else {
throw response.status;
}
});
}