为 SAM 配置 CORS。 API 适用于邮递员,但不适用于 angular
Configuring CORS for SAM. API works with postman, but not angular
我在 angular 应用程序中使用邮递员使用的相同端点注册用户时遇到问题。 Postman 工作正常并且用户出现在 cognito 用户池中没问题,但是如果我尝试通过我的 angular 应用程序中的注册页面注册用户,那么我会收到 CORS 错误
当我查看 API 网关时,我注意到不同端点中没有选项部分,所以这可能是个问题。
此外,当我部署 SAM 时,我发现没有设置授权,所以这也可能是一个因素。虽然不确定。如何配置我的 SAM 模板以使 CORS 与应用程序一起使用而不仅仅是邮递员?感谢您的帮助!
SAM 模板
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;
}
我们需要一个 OPTIONS 方法返回三个以下 headers 以便浏览器允许 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 '*'
将以下模板添加到 SAM Globals 将为指向 Mock Integration 的每个方法添加必要的 OPTIONS 方法。
所有额外的 Headers 如果有的话应该添加到 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: "'*'"
我在 angular 应用程序中使用邮递员使用的相同端点注册用户时遇到问题。 Postman 工作正常并且用户出现在 cognito 用户池中没问题,但是如果我尝试通过我的 angular 应用程序中的注册页面注册用户,那么我会收到 CORS 错误
当我查看 API 网关时,我注意到不同端点中没有选项部分,所以这可能是个问题。
此外,当我部署 SAM 时,我发现没有设置授权,所以这也可能是一个因素。虽然不确定。如何配置我的 SAM 模板以使 CORS 与应用程序一起使用而不仅仅是邮递员?感谢您的帮助!
SAM 模板
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;
}
我们需要一个 OPTIONS 方法返回三个以下 headers 以便浏览器允许 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 '*'
将以下模板添加到 SAM Globals 将为指向 Mock Integration 的每个方法添加必要的 OPTIONS 方法。
所有额外的 Headers 如果有的话应该添加到 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: "'*'"