Home

Awesome

grant-gcloud

Google Cloud Function handler for Grant

var grant = require('grant').gcloud({
  config: {/*configuration - see below*/}, session: {name: '__session', secret: 'grant'}
})

exports.handler = async (req, res) => {
  var {response} = await grant(req, res)
  if (response) {
    res.statusCode = 200
    res.setHeader('content-type', 'application/json')
    res.end(JSON.stringify(response))
  }
}

Also available for AWS, Azure, Vercel

ES Modules and TypeScript


Configuration

The config key expects your Grant configuration.

Routes

Grant relies on the request path to determine the provider name and any static override being used.

Additionally the prefix specified in your Grant configuration, that defaults to /connect, is used to generate the correct redirect_uri in case it is not configured explicitly.

Default Domain

https://[REGION]-[PROJECT].cloudfunctions.net/[LAMBDA]/connect/google
https://[REGION]-[PROJECT].cloudfunctions.net/[LAMBDA]/connect/google/callback

You have to specify the redirect_uri explicitly because the actual request URL contains the lambda name in the path, but that is never sent to your lambda handler:

{
  "defaults": {
    "origin": "https://[REGION]-[PROJECT].cloudfunctions.net"
  },
  "google": {
    "redirect_uri": "https://[REGION]-[PROJECT].cloudfunctions.net/[LAMBDA]/connect/google/callback"
  }
}

Firebase Hosting

In case you have the following rewrites configuration that proxy all requests to your grant handler:

{
  "hosting": {
    ...
    "rewrites": [
      {
        "source": "**",
        "function": "grant"
      }
    ]
  }
}
https://[PROJECT].firebaseapp.com/connect/google
https://[PROJECT].firebaseapp.com/connect/google/callback
{
  "defaults": {
    "origin": "https://[PROJECT].firebaseapp.com"
  },
  "google": {}
}

Local Routes

When running locally the following routes can be used:

http://localhost:3000/connect/google
http://localhost:3000/connect/google/callback

Session

The session key expects your session configuration:

OptionDescription
nameCookie name, defaults to grant, it have to be set to __session for Firebase Hosting!
secretCookie secret, required
cookiecookie options, defaults to {path: '/', httpOnly: true, secure: false, maxAge: null}
storeExternal session store implementation

NOTE:

Example session store implementation using Firebase:

var request = require('request-compose').client

var path = process.env.FIREBASE_PATH
var auth = process.env.FIREBASE_AUTH

module.exports = {
  get: async (sid) => {
    var {body} = await request({
      method: 'GET', url: `${path}/${sid}.json`, qs: {auth},
    })
    return body
  },
  set: async (sid, json) => {
    await request({
      method: 'PATCH', url: `${path}/${sid}.json`, qs: {auth}, json,
    })
  },
  remove: async (sid) => {
    await request({
      method: 'DELETE', url: `${path}/${sid}.json`, qs: {auth},
    })
  },
}

Handler

The Google Cloud Funtion handler for Grant accepts:

ArgumentTypeDescription
reqrequiredThe request object
resrequiredThe response object
stateoptionalDynamic State object {dynamic: {..Grant configuration..}}

The Google Cloud Funtion handler for Grant returns:

ParameterAvailabilityDescription
sessionAlwaysThe session store instance, get, set and remove methods can be used to manage the Grant session
redirectOn redirect onlyHTTP redirect controlled by Grant, it is set to true when Grant is going to handle the redirect internally
responseBased on transportThe response data, available for transport-state and transport-session only

Examples

ExampleSessionCallback λ
transport-stateCookie Store
transport-querystringCookie Store
transport-sessionFirebase Session Store
dynamic-stateFirebase Session Store

Different session store types were used for example purposes only.

Configuration

All variables at the top of the Makefile with value set to ... have to be configured:

https://[project].firebaseio.com/[prefix]
{
  "rules": {
    ".read": "auth == '[key]'",
    ".write": "auth == '[key]'"
  }
}

All variables can be passed as arguments to make as well:

make plan example=transport-querystring ...

Develop

# build example locally
make build-dev
# run example locally
make run-dev

Deploy

# build Grant lambda for deployment
make build-grant
# build callback lambda for transport-querystring and transport-session examples
make build-callback
# execute only once
make init
# plan before every deployment
make plan
# apply plan for deployment
make apply
# cleanup resources
make destroy