Error using AWS Cognito for authentication with Hasura

Viewed 368

i'm having some problems using lambda enviroment.

Looking to set a function that make a mutation to Hasura so I can relate Auth users of Cognito with my app information.

I set the following function Post Authentication in Lamba but it does not work.

function Add(event, context, callback) {
  const userId = event.user_id;
  const hasuraAdminSecret = "xxx";
  const url = "xxx";
  const upsertUserQuery = `
    mutation($userId: String!){
      insert_RegistroAnimal_users(objects: [{ id: $userId }], on_conflict: { constraint: users_pkey, update_columns: [] }) {
        affected_rows
      }
    }`
  const graphqlReq = { "query": upsertUserQuery, "variables": { "userId": userId } }

  request.post({
      headers: {'content-type' : 'application/json', 'x-hasura-admin-secret': hasuraAdminSecret},
      url:   url,
      body:  JSON.stringify(graphqlReq)
  }, function(error, response, body){
       console.log(body);
       callback(null, user, context);
  });
}

Followed this tutorial : https://hasura.io/docs/latest/graphql/core/guides/integrations/aws-cognito.html#introduction

What do you think is wrong with the code?

1 Answers

I don't think anything is wrong with the code, but to make it work with Cognito you'd need to provide your Hasura setup with a JWT claims function as shown in that same guide, https://hasura.io/docs/latest/graphql/core/guides/integrations/aws-cognito.html#create-a-lambda-function-to-add-claims-to-the-jwt. If you'd like to do it as the guide suggests, you need to create a lambda function like so;

exports.handler = (event, context, callback) => {
    event.response = {
        "claimsOverrideDetails": {
            "claimsToAddOrOverride": {
                "https://hasura.io/jwt/claims": JSON.stringify({
                    "x-hasura-user-id": event.request.userAttributes.sub,
                    "x-hasura-default-role": "user",
                    // do some custom logic to decide allowed roles
                    "x-hasura-allowed-roles": ["user"],
                })
            }
        }
    }
    callback(null, event)
}

You then need to pick this function as the PreTokenGeneration trigger from your user pool settings. Then AWS Cognito will trigger this function before token generation, allowing you to add Hasura required claims to your token.

The next step is to tell Hasura where to lookup for the JWT claims by providing HASURA_GRAPHQL_JWT_SECRET during the setup, which is essentially an URL pointing to your Cognito setup, generated using the pool id.

Finally, you can obtain the idToken from your user session after a successful login, and pass that token as an Authentication header for your Hasura requests. Described here.

All of these steps were actually described in the guide you linked, but may not be as clear. I believe the reason your current setup does not work is that your Hasura setup is missing the HASURA_GRAPHQL_ADMIN_SECRET, which needs to be the same as the x-hasura-admin-secret you're using in your requests.

Mind you, if you use x-hasura-admin-secret in your app and expose it to your users which gives them admin access, that creates a potential security issue and anyone with that secret can wipe up your data. x-hasura-admin-secret should be reserved for your admin tasks and not used in an app where AWS Cognito authentication is planned to be used.

Related