JSON web tokens

So far all the authentication examples have been based on the normal Oauth2 flow. In the developers console, you probably noticed something called a Service Account. This is normally used by server based applications to identify themselves to co-operating applications, but they can also now be used by Apps Script. This became possible by the addition of these methods to the Utilities service.

Utilities.computeHmacSha256Signature()

Utilities.computeRsaSha256Signature()

These are needed to properly sign a JWT (JSON Web Token) in which service account credentials are passed to the authentication infrastructure. I'll show how to use service accounts in a later post, but first it's worth looking at what a JWT is and how it is constructed since they are used in many different systems and platforms.

What is a JWT Token ?

The purpose of a JWT is to provide reassurance to 'B' that a message was indeed sent by the correct party (in this case 'A'), and that what was received by 'B' matches what 'A' intended to send.

It's important to realize that this is not some kind of encrypted message that can be decrypted back to its original state, but rather the message (encoded as Base64), and a digitally signed version (using a secret known to both A and B) version of the message is sent as part of the same JWT.

B can sign the unsigned message portion using the shared secret and the same signing algorithm, and if the result equals the signed message, can have confidence the the message is valid.

Firebase authentication

As an example of creating a JWT from scratch, let's look at how to generate a JWT for the Firebase noSQL database. One of the features of Firebase is to sign requests with the developer's secret key. That way Firebase can know that the request has come from a valid source and has not been modified en route.

JWT format

The structure of a JWT is

message.base64(signedmessage)

where message is

base64(header).base64(claims)

In this case, the base64 encoding is the websafe variety with padding removed as is required by the JWT specification. The claims is the object describing containing the assertions the sending party wishes to make and the header describes the algorithm and structure of the JWT itself.

message components

component

property

purpose

header

alg:”HS256”

the encryption method (the google service account uses RS256)

typ:”JWT”

identifies this as a JWT

claims

iat:Math.floor(new Date().getTime()/1000)

the time now in seconds

v:0

the version number

d:{uid:”bruce”}

any data to be passed to the security and rules processing on Firebase. This example is passing a user id.

Firebase expects the d property in the claim to contain data which is accessible in the ‘security and rules’ section of the Firebase dashboard. Typically this would be used to react in different ways depending on the passed user id.

A generated token looks like this (the message components are separated by '.')

and is passed to Firebase to prove the authenticity of the accompanying request.

The gadget spec URL could not be found

The gadget spec URL could not be found

The gadget spec URL could not be found

Code

This small module generates a JWT from your Firebase secret as follows, where data is the object you want to communicate to the Firebase security and rules processing, and secret is your Firebase developer secret (which you should store securely in the PropertiesService).

var token = FirebaseAuth.generateJWT (data, secret);

In a future post, I'll publish a JSON library for Apps Script you can use with this to access FireBase database.