user6680
user6680

Reputation: 139

Configuring CORS for SAM. API works with postman, but not angular

I'm having issues registering a user in my angular app using the same endpoint that postman uses. Postman works fine and the user appears in the cognito user pool no problem, but if I try and register the user via my registration page in my angular app, then I get a CORS error enter image description here

When I look at API gateway, I noticed there isn't an options section in the different endpoints so maybe this an issue.

enter image description here

Also when I deploy SAM I get that there is not authorization set so this could be a factor too. Not sure though. How can I configure my SAM template to make CORS work with the app and not just for postman? I appreciate any help!

SAM Template

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: REST API using SAM

Globals:
  Function:
    Runtime: nodejs12.x
    Environment:
      Variables:
        TABLE_NAME: !Ref Table
    MemorySize: 128
    Timeout: 5

Resources:
  Table:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
        Name: userid
        Type: String
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1

  ConfirmUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: confirm.handler
      Events:
        GetUser:
          Type: Api
          Properties:
            Path: /confirm
            Method: post

  RegisterUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: register.handler
      Policies: AmazonDynamoDBFullAccess
      Events:
        GetUser:
          Type: Api
          Properties:
            Path: /register
            Method: post

  LoginUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: login.handler
      Events:
        GetUser:
          Type: Api
          Properties:
            Path: /login
            Method: post

register.js

const AWS = require('aws-sdk');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
global.fetch = require('node-fetch');

const UserPoolId = "<my user poolId>"
const ClientId = "<my client id>"

const poolData = {
    UserPoolId,
    ClientId
}

AWS.config.update({
    region: 'us-east-1'
})

async function registerUser(json) {
    const {
        email,
        password
    } = json

    return new Promise((resolve, reject) => {
        let attributeList = []

        attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({ Name: "email", Value: email }));


        const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

        userPool.signUp(email, password, attributeList, null, function (err, result) {
            if (err) {
                return resolve({
                    statusCode: 500,
                    err
                })
            }

            resolve({
                statusCode: 200,
                message: 'User successfully registered'
            })
        })
    })
}

exports.handler = async function (event, context, callback) {
    console.log("EVENT BODY", event.body)
    const json = JSON.parse(event.body)
    let result;
    let response;
    try {
        result = await registerUser(json);

        response = {
            statusCode: 200,
            body: JSON.stringify('User registered successfully'),
            headers: {
                "Access-Control-Allow-Origin": "*", // Required for CORS support to work
                "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS 
            },
        };
    } catch (e) {
        response = {
            statusCode: 500,
            body: JSON.stringify('Failed to register user'),
            headers: {
                "Access-Control-Allow-Origin": "*", // Required for CORS support to work
                "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS 
            },
        };
    }

    return response;

}

Upvotes: 2

Views: 736

Answers (1)

Balu Vyamajala
Balu Vyamajala

Reputation: 10333

we need to have an OPTIONS method returning below three headers for Browser to allow CORS

Access-Control-Allow-Headers should contain all headers
Access-Control-Allow-Methods should contain all methods
Access-Control-Allow-Origin should contain the host or '*'

Adding below template to SAM Globals will add necessary OPTIONS method for every method pointing to Mock Integration.

All the additional Headers if any should be added in AllowHeaders

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"

Upvotes: 2

Related Questions