Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a billable API by linking API Keys, Usage Plans and Cognito

I've been building a serverless REST API with AWS API Gateway, Lambda and the Serverless Framework. I want to build a website on which users sign up, choose an API plan (free, basic, pro) and get the corresponding long-lived API Key with which they can query the serverless API a certain number of times a month.

I understand that with Cognito and the self-hosted UI, you can handle user authentication easily with CUP (Cognito User Pool) Tokens, which are actually Json Web Tokens. I would like to automatically create and associate an API Key to a Usage Plan, and then to the Cognito User.

The first part is easy: with the AWS Javascript SDK, it's as simple as doing:

var params = {
  keyId: 'whateverKeyId', /* required */
  keyType: 'API_KEY', /* required */
  usagePlanId: 'whateverUsagePlanId' /* required */
};
apigateway.createUsagePlanKey(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

I'm struggling with the second part... Should I add the API Key as a custom attribute to the User Pool? But then, I don't really know how to retrieve the API Key. The documentation isn't really clear. Add the user and API Key to my own DynamoDB database after sign-up (which would be a waste of Cognito really)?

To be honest, this looks like a common scenario and the fact that I spent three days looking for the solution all over the internet without success makes me think that there's something that I don't understand...

Thanks in advance for your input!

like image 718
Kévin HERRERO Avatar asked Jan 17 '20 15:01

Kévin HERRERO


People also ask

What can you use in Amazon Cognito to control who can access an API in Amazon API gateway?

As an alternative to using IAM roles and policies or Lambda authorizers (formerly known as custom authorizers), you can use an Amazon Cognito user pool to control who can access your API in Amazon API Gateway.

What are API keys in AWS API gateway?

API keys are alphanumeric strings that are distributed to developers to grant access to an API. API Gateway can generate these on your behalf, or you can import them. Usage plans let you provide API keys to your customers so that you can track and limit their usage.


1 Answers

It is a good choice to add the API key as a custom attribute in Cognito user pool.

Every time that your user signin, cognito returns an ID token in JWT format. From this token you can retrieve cognito user's attributes both the custom attr and the default. You can find further details for cognito tokens here:

https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html

and

https://aws.amazon.com/premiumsupport/knowledge-center/decode-verify-cognito-json-token/

So what you can do:

  1. Create AWS API Gateway. Create an authorizer and connect it with you AWS cognito pool. In the Request method of each for you API resource choose this new authorizer in order to authorize the user every time that he calls your API.
  2. When your user sign in in cognito, cognito returns the ID token that i described above in JWT format, pass this JWT token as your header when you make an API call.
  3. If you do the above steps, then this JWT token will be passed to your Lambda function and inside lambda function you can retrieve the cognito custom attribute (API Key):

    const API_ID = event.requestContext.authorizer.claims['custom:apiid'];
    

The above line, retrieves the JWT from your API authorizer header, and then retrieves the custom attribute that you created in cognito, which called "apiid" or however you want to name it.

like image 169
Xanthos Symeou Avatar answered Oct 12 '22 16:10

Xanthos Symeou