I have an application that accesses Google APIs out of a Chrome extension via the workflow outlined here.
Chrome Extensions OAuth Tutorial
The basics of the workflow are to initialize the OAuth flow
var oauth = ChromeExOAuth.initBackgroundPage({
'request_url': 'https://www.google.com/accounts/OAuthGetRequestToken',
'authorize_url': 'https://www.google.com/accounts/OAuthAuthorizeToken',
'access_url': 'https://www.google.com/accounts/OAuthGetAccessToken',
'consumer_key': '{MY_CLIENT_ID}',
'consumer_secret': '{MY_CLIENT_SECRET}',
'scope': 'https://www.google.com/m8/feeds/ https://apps-apis.google.com/a/feeds/emailsettings/2.0/ https://mail.google.com/',
'app_name': 'Gmail Plugin',
'callback_page': 'src/google-oauth/chrome_ex_oauth.html'
});
Upon installing the extension, the user is taken to dialog page to authenticate and agree to the scopes I ask for. From here I infer that my consumer key and secret are OK. I have allowed access to the GMail, Contacts, and Admin SDK in the Google Developers console.
Prior to this I had requests working with the Contacts API and Admin SDK API. I'm now trying to add some features that utilize the Gmail REST API.
The next step in setting up a request is to make a request from the background page.
function getSentEmails() {
var emailCollection;
var url = "https://www.googleapis.com/gmail/v1/users/me/messages";
var request = {
'method': 'GET',
'parameters': {
'labelIds': 'SENT'
}
};
var callback = function(response, xhr) {
emailCollection = JSON.parse(response);
console.dir(emailCollection);
}
oauth.sendSignedRequest(url, callback, request);
};
The way the signed requests work is to call a method to complete the next step of the OAuth dance,
oauth.authorize(function() {
getSentEmails();
});
This results in a 403 Forbidden every time. I seem to have no issue accessing the other APIs I mentioned though this OAuth flow. I've allowed the scope in my manifest.json
manifest.json
"permissions": [
"tabs",
"storage",
"https://mail.google.com/*",
"https://www.google.com/m8/feeds/*",
"https://apps-apis.google.com/a/feeds/emailsettings/2.0/*",
"https://www.googleapis.com/gmail/v1/users/*",
"https://www.googleapis.com/auth/gmail.modify/*",
"https://www.googleapis.com/auth/gmail.compose/*",
"https://www.googleapis.com/auth/gmail.readonly/*",
"https://www.google.com/accounts/OAuthGetRequestToken",
"https://www.google.com/accounts/OAuthAuthorizeToken",
"https://www.google.com/accounts/OAuthGetAccessToken"
]
I tried an alternate method of building the HTTP request as outlined in the link above.
function stringify(parameters) {
var params = [];
for(var p in parameters) {
params.push(encodeURIComponent(p) + '=' +
encodeURIComponent(parameters[p]));
}
return params.join('&');
};
function xhrGetSentEmails() {
var method = 'GET';
var url = 'https://www.googleapis.com/gmail/v1/users/me/messages';
var params = {'labelIds': 'SENT'};
var callback = function(resp, xhr) {
console.log(resp);
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(data) {
callback(xhr, data);
};
xhr.open(method, url + '?' + stringify(params), true);
xhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
xhr.send();
}
I get the same 403 doing this.
I believe I'm authenticating properly though, because if I change
xhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
to
xhr.setRequestHeader('Authorization','foo' + oauth.getAuthorizationHeader(url, method, params));
I get a 401 Unauthorized instead.
Again, no trouble accessing the other APIs I mentioned.
Any input would be much appreciated.