Giter Club home page Giter Club logo

calculator-api's Introduction

Welcome to the Calculator API projet!

This is a demo project to deploy a calculator API using AWS CDK v2 with Python.

The application is based on

  • AWS HTTP API serverless API Gateway for the API endpoints,
  • Two Lambda functions, onr for addition the second for substraciton.
  • Cognito for Authentication using OAuth2
  • Route 53 to create the DNS record for the API endpoints

Caclulator API Architecture

Environment Setup

The cdk.json file tells the CDK Toolkit how to execute your app.

This project is set up like a standard Python project. The initialization process also creates a virtualenv within this project, stored under the .venv directory. To create the virtualenv it assumes that there is a python3 (or python for Windows) executable in your path with access to the venv package. If for any reason the automatic creation of the virtualenv fails, you can create the virtualenv manually.

To manually create a virtualenv on MacOS and Linux:

$ python -m venv .venv

After the init process completes and the virtualenv is created, you can use the following step to activate your virtualenv.

$ source .venv/bin/activate

If you are a Windows platform, you would activate the virtualenv like this:

% .venv\Scripts\activate.bat

Once the virtualenv is activated, you can install the required dependencies.

$ pip install -r requirements.txt

At this point you can now deploy the CloudFormation template for this code. Assign DNS_DOMAIN a DNS domain from your Route53 account

$ export CDK_DEFAULT_ACCOUNT=012345678910
$ export CDK_DEFAULT_REGION='us-east-1'
$ export DNS_DOMAIN='YOUR_ROUTE53_DOMAIN'
$ cdk synth

This will deploy the API HTTP with the custom domain https://calculator-api.my-domain.com The authentication will done with the endpoint https://calculator-api.my-domain.com/oauth2/token

Get OAuth2 token

There are many GUIs you can use to generate the JWT token like Postman or Insomnia. We'll use here the old curl command

Get first the UserPoolID and the UserPoolClientID created by the CDK

Alt text

Uset them with aws cognito-idp to get the ClientId and the ClientSecret

$ aws cognito-idp describe-user-pool-client --user-pool-id us-east-1_LX6a3ggxu --client-id 618jhi0ako4kukld7rsh8tuq2g
{
    "UserPoolClient": {
        "UserPoolId": "us-east-1_LX6a3ggxu",
        "ClientName": "Client1",
        "ClientId": "618jhi0ako4kukld7rsh8tuq2g",
        "ClientSecret": "e174jlu5mdkr6o1vedp5tvc4rs6lei1nqlapufjc14lup7lhim5",
        "LastModifiedDate": "2021-12-22T14:30:31.698000-05:00",
        "CreationDate": "2021-12-22T14:30:31.698000-05:00",
        "RefreshTokenValidity": 30,
        "TokenValidityUnits": {},
        "ExplicitAuthFlows": [
            "ALLOW_CUSTOM_AUTH",
            "ALLOW_REFRESH_TOKEN_AUTH",
            "ALLOW_USER_SRP_AUTH"
        ],
        "SupportedIdentityProviders": [
            "COGNITO"
        ],
        "AllowedOAuthFlows": [
            "client_credentials"
        ],
        "AllowedOAuthScopes": [
            "UserPoolResourceServer/json.read"
        ],
        "AllowedOAuthFlowsUserPoolClient": true,
        "PreventUserExistenceErrors": "ENABLED"
    }
}

We'll convert the ClientId and ClientSecret to generate the JWT token (in Base64)

$python
>>> import base64
>>> base64_encoded=base64.b64encode(b'618jhi0ako4kukld7rsh8tuq2g:e174jlu5mdkr6o1vedp5tvc4rs6lei1nqlapufjc14lup7lhim5')
>>> print(base64_encoded)
b'NjE4amhpMGFrbzRrdWtsZDdyc2g4dHVxMmc6ZTE3NGpsdTVtZGtyNm8xdmVkcDV0dmM0cnM2bGVpMW5xbGFwdWZqYzE0bHVwN2xoaW01'

We'll use that JWT token to authenticate with the API HTTP Gateway using the endpoint /oauth2/token

$ curl --location --request POST 'https://calculator-api.my-domain.com/oauth2/token?grant_type=client_credentials&client_id=618jhi0ako4kukld7rsh8tuq2g$scope=AuthIdentifier/json.read' \
                    --header 'Authorization: Basic NjE4amhpMGFrbzRrdWtsZDdyc2g4dHVxMmc6ZTE3NGpsdTVtZGtyNm8xdmVkcDV0dmM0cnM2bGVpMW5xbGFwdWZqYzE0bHVwN2xoaW01' \
                    --header 'Content-Type: application/x-x-www-form-urlencoded'

{"access_token":"eyJraWQiOiJRcHNTWU5oVjJFRzNpQ1d6bDd2SVM4N....................................","expires_in":"3600","token_type":"Bearer"}

Query the API endpoints with OAuth2 token

Now we can query the API Gateway using this token

$ curl --location --request GET 'https://calculator-api.my-domain.com/minus?val1=3&val2=10' \
        --header 'Content-Type: application/json' --header 'Authorization: Bearer eyJraWQiOiJRcHNTWU5oVjJFRzNpQ1d6bDd2SVM4N....................................' \
        --header 'Content-Type: application/json'
7

The result 7 (=10-3) is returned from the Lambda lambda_minus

However, the default route (in our case the root path) doesn't need authentication

$ curl --request GET https://calculator-api.my-domain.com
Hello! This is the default route.
 received event: {"version": "2.0", "routeKey": "$default", "rawPath": "/", "rawQueryString": "", "headers": {"accept": "*/*", "content-length": "0", "host": "calculator-api.my-domain.com", "user-agent": "curl/7.75.0", "x-amzn-trace-id": "Root=1-61c38f44-6762a5b730fd53e1428fcaab", "x-forwarded-for": "44.33.22.11", "x-forwarded-port": "443", "x-forwarded-proto": "https"}, "requestContext": {"accountId": "012345678910", "apiId": "f9va58ihri", "domainName": "calculator-api.my-domain.com", "domainPrefix": "calculator-api", "http": {"method": "GET", "path": "/", "protocol": "HTTP/1.1", "sourceIp": "44.33.22.11", "userAgent": "curl/7.75.0"}, "requestId": "KxNSxgU2IAMEVvc=", "routeKey": "$default", "stage": "$default", "time": "22/Dec/2021:20:49:08 +0000", "timeEpoch": 1640206148700}, "isBase64Encoded": false}(.venv)

Enjoy!

calculator-api's People

Contributors

kerbachi avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.