
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' } ); }
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.
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.
- 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.
Next step will be to implement it as a rest library option.