Accessing GMail API from chrome extension? 403 Forbidden

I have an app that accesses a Google API from a Chrome extension through the workflow described here.

Chrome Extensions Tutorial

Workflow basics - initialize 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'
});

      

After installing the extension, the user is taken to a dialog page to authenticate and negotiate the scopes I am asking for. From this I concluded that my key and secret for the consumer is in order. I have enabled access to GMail, Contacts and Admin SDK files in the Google Developers Console.

Before that, I had requests related to the Contacts API and the Admin API. Now I am trying to add some functionality that uses the Gmail REST API.

The next step in setting up a request is to make a request from the man 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 signed requests work is to call the method to complete the next step of the OAuth dance,

oauth.authorize(function() {
    getSentEmails();
  });

      

This results in a 403 ban every time. I seem to have no problem accessing the other APIs I mentioned, although this OAuth thread. I have allowed 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 alternative method of constructing an HTTP request as above in the link.

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 as 403.

I believe I am authenticating correctly, because if I change

xhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));

      

to

xhr.setRequestHeader('Authorization','foo' + oauth.getAuthorizationHeader(url, method, params));

      

I get 401 Unauthorized instead.

Again, no problem accessing the other APIs I mentioned.

Any input would be much appreciated.

+1


source to share


1 answer


This question is probably quite unclear, so I'll share how I solved it.

I have moved chrome extensions OAuth 2.0 to the new (since Chrome 29) chrome.identity for apps and extensions.

Detailed instructions on setting up OAuth 2.0 for an extension are provided here.

Chrome Authentication API user authentication



Now I can use

chrome.identity.getAuthToken(function(token) {
  // Do HTTP API call with token
});

      

And none of my HTTP requests are denied anymore (403).

Hope this is helpful for extension developers!

+4


source







All Articles