0

I got some troubles configuring an Hasura auth hook using a Lambda. I need such a function as I am storing my JWT token in an HTTP-only cookie, for security reasons.

I'm using a serverless function which returns a correct response (either when testing a curl request directly, or even when logging lambda):

{
    "statusCode":200,
    "body":"{\"X-Hasura-User-Id\":\"74d3bfa9-0983-4f09-be02-6a36888b382e\",\"X-Hasura-Role\":\"user\"}"
}

Yet, Hasura hook doesn't seem to recognize the response:

{
    "type": "webhook-log",
    "timestamp": "2020-02-07T10:27:34.844+0000",
    "level": "info",
    "detail": {
        "response": null,
        "url": "http://serverless:3000/auth",
        "method": "GET",
        "http_error": null,
        "status_code": 200
    }
}

These two lines of logs are adjacent in my logs. I just reformatted them a little bit to ease reading.

My lambda code looks like:

export const handler = async (event) => {
    const cookies = getCookiesFromHeader(event.headers);
    const { access_token: accessToken } = cookies;

    let decodedToken = null;

    try {
        const cert = fs.readFileSync("./src/pem/dev.pem");
        decodedToken = jwt.verify(accessToken, cert);
    } catch (err) {
        console.error(err);
        return {
            statusCode: 401,
        };
    }

    const hasuraClaims = decodedToken['https://hasura.io/jwt/claims'];

    return {
        statusCode: 200,
        body: JSON.stringify({
            "X-Hasura-User-Id": hasuraClaims['x-hasura-user-id'],
            "X-Hasura-Role": hasuraClaims['x-hasura-default-role']
        })
    }
}

Any idea on what is going on? Note that I'm using serverless offline, in case of. :)

Jonathan Petitcolas
  • 4,254
  • 4
  • 31
  • 42

1 Answers1

1

In AWS Lambda, the spec requires the response body to be stringified and the actual response will be a parsed JSON object which is what Hasura will receive from the auth webhook.

When you are using serverless-offline, the response body is returned as a String (since JSON.stringify is used) without getting parsed. A simple curl will give you the difference.

The above code will work on Lambda but not on local development using serverless-offline. You will have to use the event object to see if isOffline is true and return JSON directly and if not return the stringified version.

Example code:

if(event.isOffline) {
 // make it work with serverless-offline
 return { "x-hasura-role": "user" ....};
} else {
 // make it work with lambda
 return { statusCode: 200, body: JSON.stringify({"x-hasura-role": "user"}) };
}

Official example in the serverless-offline repo along with error handling.

Related issues:

praveenweb
  • 743
  • 4
  • 15