Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using AWS Cognito in a Lambda function with npm

I'm trying to use AWS Cognito in a Lambda function to authorize a user.

I have some sample code from a Udemy Course (no longer available): https://www.udemy.com/minimum-viable-aws-cognito-user-auth-in-javascript

The code uses the script files:

aws-cognito-sdk.min.js amazon-cognito-identity.min.js

The second seems to available by npm as: amazon-cognito-identity-js

The first file is supposed to be a cut down version of the aws-sdk with just the Cognito api components. The full aws-sdk is available from npm as: aws-sdk but I cannot find the cutdown version in npm.

Is the cutdown file: aws-cognito-sdk.min.js available in npm?

EDIT: According to Russell I should use the aws-sdk package.

So if I have code:

const AWS = require('aws-sdk');

var authenticationDetails = new AWS.AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);

I get the error:

Cannot read property 'CognitoIdentityServiceProvider' of undefined

What is the correct path to AuthenticationDetails?

like image 765
Greg Pagendam-Turner Avatar asked Jan 18 '18 03:01

Greg Pagendam-Turner


People also ask

Can you use NPM with Lambda?

You can reuse the lambda layer for multiple functions. You can even include multiple npm modules or even your own helper functions that you reuse between your lambdas. You can use up to five layers in a single lambda function.

Can I use Cognito as an IdP?

Amazon Cognito supports authentication with identity providers (IdPs) through Security Assertion Markup Language 2.0 (SAML 2.0). You can use an IdP that supports SAML with Amazon Cognito to provide a simple onboarding flow for your users. Your SAML-supporting IdP specifies the IAM roles that your users can assume.


2 Answers

For Lambdas use the aws-sdk module as such:

const { CognitoIdentityServiceProvider } = require('aws-sdk')
//or 
const CognitoIdentityServiceProvider = require('aws-sdk/clients/cognitoidentityserviceprovider') // Much smaller size

For authentication use the AdminInitiateAuth method.

  const cognitoProvider =  new CognitoIdentityServiceProvider({
      apiVersion: '2016-04-18',
      accessKeyId:...
      secretAccessKey: ...
      region:...
    })

    await cognitoProvider.adminInitiateAuth(...)

The amazon-cognito-identity-js package is meant for frontend clients (React, React Native, etc). It contains only the functionality necessary to connect to Cognito. It does not require the aws-sdk module (unless you need extra features).

While you may be able to use the amazon-cognito-identity-js for your use case it's far from ideal as you are just pretending to be an unauthenticated user with limited functionality compared to loading the admin method using your api key thereby providing you with much more functionality.

like image 83
cyberwombat Avatar answered Oct 14 '22 02:10

cyberwombat


Got this working.

package.json needs dependencies:

"amazon-cognito-identity-js": "^1.31.0",
"aws-sdk": "^2.182.0",

AWS Lambda does not use Javascript ES6 and so you can't use the 'import' keyword.

        const AWS = require('aws-sdk');

        var AmazonCognitoIdentity = require('amazon-cognito-identity-js');
        var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
        var AuthenticationDetails = AmazonCognitoIdentity.AuthenticationDetails;
        var CognitoUser = AmazonCognitoIdentity.CognitoUser;

        var poolData = {
            UserPoolId: 'THE USER POOL ID',
            ClientId: 'THE CLIENT ID'
        };
        var userPool = new CognitoUserPool(poolData);

        AWS.config.region = 'AWS_REGION';
        AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: 'THE USERPOOL ID',
        });
        var email = "[email protected]";
        var password = "password";

        var authenticationData = {
            Username: email,
            Password: password
        };
        var authenticationDetails = new AuthenticationDetails(authenticationData);

        var userData = {
            Username: email,
            Pool: userPool
        };

        var cognitoUser = new CognitoUser(userData);

        console.log(result);
        cognitoUser.authenticateUser(authenticationDetails, {
            onSuccess: function (result) {
              console.log('access token + ' + result.getAccessToken().getJwtToken());
              callback(null, result);
            },

            onFailure: function (err) {
              console.log('Login error: ' + err);
              callback(null, result);
            }
        });
like image 43
Greg Pagendam-Turner Avatar answered Oct 14 '22 01:10

Greg Pagendam-Turner