skip to Main Content

In my app, the user can authenticate via AWS Cognito User Pools or Facebook all managed an AWS identity pool. That’s all working correctly, the user can login and authenticate successfully. Now, I need to make authenticated requests to an AWS Gateway API which will then trigger Lambda functions. I’m confused as to what comes next. Do I need to write code to sign these requests or does the AWS javascript SDK already have something built in for this? Do I need to create an Authorizer? How do I go from AWS.config.credentials to making successful, authenticated requests to a Gateway API?

I’m using React Native so the auto generated APIs won’t work.

EDIT: Here’s my request code:

fetch('https://MY_API_GATEWAY_URL/prod/handleMessages/', {
method: 'GET',
body: null,
headers: {
Authorization: 'Bearer ' + this.state.token, /* this is the JWT token from AWS Cognito. */
},
})
.then((response) => {
alert(JSON.stringify(response, null, 2))
})

I get 403 response from this with the exception: IncompleteSignatureException

3

Answers


  1. At this point you should have a valid Cognito issued JWT. To call APIs behind AWS API Gateway you need to pass the JWT along with your API calls. This should go in the Authorization header with type of Bearer. You can determine whether a custom authorizer is necessary or just use the built in authorization with API Gateway.

    Additional info can be found here –
    http://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html

    You also need to ensure IAM rules are in place to allow the UserPool to access the API Gateway endpoints –
    http://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html

    Login or Signup to reply.
  2. You can generate the JWT token from Server-side, after AWS Cognito UserPools Authentication, using a API Gateway Endpoint. e.g /<stage>/authenticate

    var authenticationData = {
        Username : 'username',
        Password : 'password',
    };
    var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
    var poolData = { UserPoolId : 'us-east-1_TcoKGbf7n',
        ClientId : '4pe2usejqcdmhi0a25jp4b5sh3'
    };
    var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
    var userData = {
        Username : 'username',
        Pool : userPool
    };
    var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function (result) {
            console.log('access token + ' + result.getAccessToken().getJwtToken());
            /*Use the idToken for Logins Map when Federating User Pools with Cognito Identity or when passing through an Authorization Header to an API Gateway Authorizer*/
            console.log('idToken + ' + result.idToken.jwtToken);
        },
    
        onFailure: function(err) {
            alert(err);
        },
    
    });
    

    For more details, check this example.

    After the authentication send the jwtToken back to the React Native app, where it needs to be sent in Authorization header with the token for subsequent API requests.

    At API Gateway configure user pool authorizer in integration method configuration, so that it will automatically validate the authorization header and load user context information for the endpoint.

    Login or Signup to reply.
  3. You can use the AWS Amplify library’s API module which will automatically sign requests: https://github.com/aws/aws-amplify

    For React Native this is available via npm:

    npm install aws-amplify-react-native
    

    If using Cognito User Pools link the library as outlined here: https://github.com/aws/aws-amplify/blob/master/media/quick_start.md#react-native-development

    The API module will have you configure a friendly name for your endpoint and also the Invocation URL from an API Gateway stage. Then you simply call the HTTP method and pass optional parameters as options:

    import Amplify, {API} from 'aws-amplify-react-native';
    Amplify.configure('your_config_file_here');
    API.get('apiname', 'invokeURL', options).then(res=>{
        console.log(res);
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search