It’s been a few years since I first created the Goa library. Initially it was mainly to provide OAuth2 authorization and authentication to be able to access Google APIS and services unavailable via App Script. Nowadays of course, most of that can easily done by adding scopes to your appsscript.json manifest.
However Goa supports services other than Google, and flows other than the usual 3 legged oauth2. This is just a refresher on how Goa works and how to use it using the Twitter 2 API as an example.
Motivation
Twitter now have a v2 API which uses Oauth2. For their previous API version, you could use Oauth1 or other less secure methods of authentication. Their implementation of Oauth2 is a little funkier than most, so it Goa needed a few more tweaks to support it. That reminded me that I hadn’t posted about it for a while, so here is a complete refresher on Goa, Oauth2 and Apps Script.
I’ll use Twitter as an example provider throughout this article, but it’s a similar process whoever the service provider is.
Why Oauth2 is needed
There are 2 functions of Oauth2
- Authentication – making sure that you are who you say you are by having you login into a trusted source – a resource provider like twitter – before running a script on your behalf
- Authorization – ensuring that the function your script is trying to perform on your behalf is one that it is allowed to
Authentication
Let’s say your script wants to access your twitter account. One way would be to somehow build your user name and password into your script. However that means
- Anyone who saw your script would now know your twitter password
- If you changed your password on twitter, you’d also need to change it in your script
OAuth2 aims to ensure that your script can get your resources securely from twitter without having to manage or even know you or your twitter credentials.
- The script is allowed to access twitter by knowing credentials supplied by twitter (clientId and clientSecret)
- The script oversees you logging in to twitter – and on successful login, twitter returns a code specific to your account using a callback url to your script which matches one that twitter is expecting the given clientId to be able to handle
- The script uses that code to exchange for an access token when it needs to access twitter on your behalf. This access token can be used till it nears expiry, but it can be refreshed using a refresh token which the OAuth2 process provided in the initial stage
Authorization
OAuth2 handles authorization using ‘scopes’. These describe collections of the API and the authority to perform certain actions on them. Each API is different and has a different scheme for defining their scopes. OAuth2 combines the notion of scopes that permit access with authentication that identify a friendly actor to produce a token back to the API which allows a certain level of access to resources belonging to a given individual.
What is Goa
It’s an Apps Script library to allow a serial approach to authentication (proving who you are) and authorization (allowing access to required resources). In other words, your script doesn’t have to get involved in the mysteries of figuring out endpoints, handling callbacks, deciphering state digests, and refreshing the tokens that inhabit the world of Oauth2.
Goa 3 Legged oauth2 works like this
These are generally one off operations
- Get credentials from your OAuth2 provider developer console
- Tell Goa about them. Goa takes care of the nuances of each known provider’s rules for OAuth2.
- Run a webapp which will give you a url to put in your developer console and login into your provider’s site via Goa
Then each time you need to access a provider resource
- Ask Goa for a token to put in your request header. Goa keeps note of the latest token it received from your provider and gives you that if it hasn’t expired. If it has expired it will automatically and silently get a new one for you
Example
Let’s say you’ve already gone through the preparation steps and you have a script that needs a token to access a service. You can run a server side script like this. If Goa detects that needs to go off and get a new access token because the old one has expired, it’ll do it automatically.
Preparation
You’ll need the cGoa library added to your script – details at the end.
These are steps you’ll normally need to do just once.
This is using the Twitter developer console, but all oauth2 providers have a similar console in which to do all of this.
Go to twitter developer console and create an app
Edit your app settings
Upload a logo
In Settings, upload a logo if you have one, or just leave the default.
Here’s the twitter/goa logo in case you want to use it
Keys
In Keys and Tokens, go down to the Oauth2 section and get your clientId and clientSecret. You don’t need to bother about the other stuff on this page – that’s for other kinds of less secure authentication.
Turn Oauth2 on
By default OAuth2 isn’t on – turn it on.
Setting up the credentials in Apps Script
Now we’ll go over to your Script, and set up the client id and secret in a property store. Which property store to use depends on the scenarios your use case will support, and I’ll touch on later, but quite often it’s going to be in the UserProperties Store.
create and run a once off script
- the clientid and secret from the twitter developer console
- some name you’ll use to refer to this credential set later
- scopes that will authorize access to the twitter resources you need to access. I’m going to use this to do twitter queries, so these are the scopes I need. You’ll find all the twitter API scopes here.
Run the script – you won’t need it again so when you’re finished testing, delete it from your script so as not to accidentially expose these credentials.
create a once off doGet function
In order to get the auth process going (Run a once off webapp which will give you a url to put in your developer console and login into your provider’s site via Goa), we’ll need a temporary simple web app.
Deploy the webapp
The IDE test deployment selection is fine for this. Click on the link it shows and it’ll take you into a dialog like this if it detects that it’s necessary to get consent.
That will bring up this consent dialog (the checkbox is to allow tokens to be sliently refreshed without and further human intervention)
Copy the Redirect URI from the dialog
Enter redirect URI in Twitter console
Paste that redirect URI from the consent dialog into your Twitter developers console so that when Twitter receives the request from your script and returns the authentication code it knows it’s definitely returning it to a valid script associated with your clientId.
You’ll find this under the Oauth2 settings that you turned on earlier.
You can usually have multiple redirect URIs associated with the same client, allowing you to create multiple projects using the same credentials.
Complete the consent dialog
Now that twitter knows that it can respond to your script safely, you can complete the consent dialog from your webapp with the Start button, and twitter will (possibly ask you to login to twitter if you’re not already logged in and) present you with this dialog
Get your access token and use it
If this is actually your web app you can go ahead and use the access token right away. In any case, it’s ready to be used now and the future by any web apps or server side scripts in your Apps Script project without any further action.
You can remove this web app and the once off credential function now.
Property Services
Here’s a guide on which property service to use.
- If the script is to run as you – ie. access a resource belonging to you, and only you will be running the script, then use UserProperties – you’ll give access to your resource the first time you run it.
- If the script is to run as you – ie. access a resource belonging to you, but others will be running the script accessing your resources then use ScriptProperties – you’ll give access to your resource the first time you run it.
- If the scipt is to run as the user accessing the script – then it’s a little more complex as the credentials will need to be cloned to each new user for them to login into and give access to their resource the first time they use it while keeping individual tokens private to them. To support this scenario, initialize goa once off in ScriptProperties, and make the code below the first thing you do in your script. Goa will clone the credentials to the user’s property store the first time it sees them, will force an authentication and thereafter will maintain a separate thread of access/refresh tokens for each user.
There may be a reason to use DocumentProperties as well, but I can’t think of one for now.
Next
You may have come across my posts on SuperFetch – a proxy enhancement to Apps Script UrlFetch. I have a Twitter V2 API plugin for SuperFetch in the works that I’ll write up shortly in another article, and we’ll be using goa as a tokenService for that plugin.
Links
cGoa library 1v_l4xN3ICa0lAW315NQEzAHPSoNiFdWHsMEwj2qA5t9cgZ5VWci2Qxv2