Client oAuth calls using a Google Apps scriptDB lockbox

oAuth  arghhh..

When I was looking around for a way to easily implement oAuth, and be able to use it from multiple scripts, or even languages (I was originally trying to figure out how to do it from VBA), I came across lots of different oAuth implementations, mainly using server based code, but all of which had some challenges in either keeping the secret key information secure, yet available, or in actually implementing a native oAuth solution because of cross domain challenges, lack of libraries and so on.  I wondered if there might be an easy way to solve this using google Apps Script as a proxy for accessing REST queries that required oAuth.

Here’s how to, without needing a server,

  • keep your oAuth credentials in a lockbox shared amongst all your scripts and outside of Google Script through a rest query.
  • access URLs needing oAuth by proxy so you don’t have to build in the oAuth code to your scripts
  • Do rest queries that need oAuth using Google Apps as a proxy.

Keeping your keys secure, yet available.

In using google apps scriptdb as a lockbox I covered how to use scriptDB to store private information that could be shared amongst multiple scripts that you own.

Here’s how to use that concept to store your oAuth keys. You’ll need to use the shared mcpher library, which contains all the code we will reference here.

  • Create a private script, with a private scriptDB. I’ve called it myStuff. It has only 2 functions in it. doGet() will be called when you access this through a URL, and myStuffDb() will be able to provide the privateDB you are sharing all this in to other scripts you own. The code below can be used without any modification.
     function doGet(e) {
       return ContentService
            .createTextOutput(mcpher.getStuffContent (e,myStuffDb()))
            .setMimeType(ContentService.MimeType.JSON); ;     
      }
      function myStuffDb(){
           return ScriptDb.getMyDb();
      }
  • Make myStuff into a library – as described here,  publish it as a web app, accessible only to you. The published link is what you are going to use to proxy oAuth calls with.
  • Create another script. We are going to use this one to test from. Set it up to access the myStuff library you have just created, as well as the  shared mcpher library.
  • Add a function to store some credentials in your private scriptDB. You will have got these as you registered your application with your API provider. In this example, I’m planning to use the linkedin api. I’m going to refer to these credentials in future as the “linkedinauth” lockbox. You could of course create a form to collect this information if you want, but this is how to store them.
    function createLinkedInAuth(){
      return mcpher.createStuff ("linkedinauth",  myStuff.myStuffDb(), {
        consumerKey: 'your consumer/api key',
        consumerSecret: 'your consumer secret',
        requestUrl: 'https://api.linkedin.com/uas/oauth/requestToken',
        accessUrl: 'https://api.linkedin.com/uas/oauth/accessToken',
        authorizeUrl: 'https://api.linkedin.com/uas/oauth/authorize'
       } );
    }
Note:
For some APIS you may also need to specify a callback – even if you are not going to use it. This is true for twitter and linkedin for example. To make this work, I simply created a dummy script with a doGet() function that does nothing, published it, and used that as the callback for all APIS.
You are now ready to access your app either as a rest proxy, or directly from google apps script.
Testing
It’s easier to do this directly from apps script, so let’s test it like that. The first time you associate your application, you need to authorize it, so you’ll need a function like this to help test.
function testLinkedin() {
  var e ={};
  e.parameter ={};
  e.parameter.action = "oauth";
  e.parameter.proxyurl = encodeURIComponent("http://api.linkedin.com/v1/people/~?format=json");
  e.parameter.entry = "linkedinauth";

  Logger.log(mcpher.getStuffContent (e,myStuff.myStuffDb(),true));
  return e;
}

If you run this, do the one time authorization when asked, and check the log you should see the result of running the query. Here’s a snippet of what i got back

{
  "firstName": "Bruce",
  "headline": "Information Technology and Services Professional",
  "lastName": "McPherson",
  "siteStandardProfileRequest": {"url": "http://w.... etc"}

}
Now it works,  you are ready to try as a rest query – first from the browser.

Accessing from the browser or as a rest query

Again we will use the linked in example. The format of the rest call is
your-web-app-link?entry=linkedinauth&action=oauth&proxyurl=urlencoded-linktoexecute
 
Summary
Now we have
  • A place to store oauth credentials
  • A way to have queries that require oAuth authenticated and executed on our behalf by Google Apps Script without needing to build those credentials into multiple places.

 

You can find a snapshot of the library code for this in this gist, https://gist.github.com/3714035, and of course in the shared mcpher library,

Next step will be to implement it as a rest library option.

About brucemcp 225 Articles
I am a Google Developer Expert and decided to investigate Google Apps Script in my spare time. The more I investigated the more content I created so this site is extremely rich. Now, in 2019, a lot of things have disappeared or don’t work anymore due to Google having retired some stuff. I am however leaving things as is and where I came across some deprecated stuff, I have indicated it. I decided to write a book about it and to also create videos to teach developers who want to learn Google Apps Script. If you find the material contained in this site useful, you can support me by buying my books and or videos.