Amazon web services 如何保护AWS API网关URL免受未经授权的访问?
我想在AWS S3中托管我的静态网站。但它包含“联系我们”页面,用于发送电子邮件。当用户点击提交按钮时,将请求发送到AWS API网关,API网关触发lambda函数;lambda函数将邮件发送给Admin 但它有一些问题。当我们在服务器上托管网站时,我们可以使用验证码来防止提交请求自动化和欺诈活动。在这种情况下,任何人都可以误用(通过在URL中传递查询字符串来发送更多请求)我的API网关URLAmazon web services 如何保护AWS API网关URL免受未经授权的访问?,amazon-web-services,amazon-s3,aws-lambda,aws-api-gateway,Amazon Web Services,Amazon S3,Aws Lambda,Aws Api Gateway,我想在AWS S3中托管我的静态网站。但它包含“联系我们”页面,用于发送电子邮件。当用户点击提交按钮时,将请求发送到AWS API网关,API网关触发lambda函数;lambda函数将邮件发送给Admin 但它有一些问题。当我们在服务器上托管网站时,我们可以使用验证码来防止提交请求自动化和欺诈活动。在这种情况下,任何人都可以误用(通过在URL中传递查询字符串来发送更多请求)我的API网关URL 因此,我的问题是如何知道提交请求仅从我的网站请求,是否有任何方法可以代替Captcha使用?您可以在
因此,我的问题是如何知道提交请求仅从我的网站请求,是否有任何方法可以代替Captcha使用?您可以在http上使用Referer标头。它由浏览器设置 谷歌的reCAPTCHA看起来很容易集成- 这就打破了-
无论如何,为什么不设计你自己的验证机制(如果你真的想自己做的话:)?在让用户提交之前(或提交时…)询问用户的电话号码。然后调用API网关端点,该端点获取该号码并通过SNS发送otp。一旦用户验证此otp(另一个api网关调用),则只发送管理员电子邮件(进行进一步处理)。您可以将此otp存储为带有已验证布尔标志的某些RD。您不必担心这些API网关端点,因为它们实际上仅用于身份验证,并且可以通过云端自动缩放。使用API网关和Lambda验证reCAPTCHA 对于S3静态站点上的无服务器SPA站点上的联系人表单,我使用AngularJS和“angular recaptcha”服务(),尽管您可以使用任何方式获取和发布recaptcha值 在后端,您可以使用API网关调用Lambda函数来验证recaptcha值并执行某些操作。使用NodeJS和Recaptcha2()验证令牌
var reCAPTCHA = require('recaptcha2')
module.exports.sendemail = (event, context, callback) => {
// parse the data that was sent from API Gateway
var eventData = JSON.parse(event.body);
// Prepare the recaptcha connection to Google
var recaptcha = new reCAPTCHA({
siteKey: process.env.RECAPTCHA_KEY,
secretKey: process.env.RECAPTCHA_SECRET
})
// Validate the recaptcha value
recaptcha.validate(eventData.recaptcha)
.then(function(){
// validated ok
console.log("ReCaptcha Valid")
... DO STUFF HERE ...
})
.catch(function(errorCodes){
// invalid recaptcha
console.log("ReCaptcha Not Valid")
// translate error codes to human readable text
console.log(recaptcha.translateErrors(errorCodes));
// send a fail message with cors headers back to the UI
var response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Error: Invalid Recaptcha"})
}
callback(null, response);
});
};
使用把手和SES的模板电子邮件示例
作为奖励,以下是我使用html/文本模板发送电子邮件时重用的一些代码:
- 将值注入模板SES以发送电子邮件的手柄
- 确保您已使用域名设置SES,并允许Lambda使用“SES:sendmail”和“SES:sendmailraw”李>
- 在部署函数时添加环境变量,这使得代码可以重用,并且不让源代码泄露秘密
- 我强烈建议使用无服务器框架来部署无服务器应用程序李>
编辑:修复语法错误您可以通过谷歌验证码实现同样的效果,因为对于每个请求,都需要使用验证码创建会话,验证码通过API验证。为什么要使用验证码以外的东西?我们不打算使用任何服务器,那么验证码将如何验证使用API网关和Lambda验证验证码。另一个选项是使用CloudFront和AWS WAF进行基于速率的阻塞。我们可以在我们的网站中使用google captcha吗?该网站位于AWS S3 Bucket中,只有在S3中才能使用。你不能这样做,你可以在静态页面中显示,但需要从后端进行验证。您可以使用API网关和Lambda作为后端来验证验证码。referrer标头对我的场景有多有用?点击submit后,只需在HttpRequest中查看标头referrer即可。。我觉得推荐人会给你你的网页谢谢,但我毫不怀疑。我使用api网关url通过查询字符串传递表单数据,并使用后端python lambda函数发送邮件。如果我在表格中添加谷歌验证码。如何通过用户在google captchain php中输入的api网关url中的查询字符串传递数据我们这样做是为了存储在变量$data=$\u POST['g-recaptcha-response']中,如何在javascript
var eventData=JSON.parse(event.body)中进行同样的操作
获取输入变量,然后eventData。recaptcha
是recaptcha值。与eventData.contactFormMessageFromUser
或'eventData.contactFormEmailAddressFromUser`相同,例如,您可以使用eventData。['g-recaptcha-response']
获取recaptcha的post值。(带连字符的变量名格式的更改不能以同样的方式访问,应该避免)。谢谢,但我毫不怀疑。我使用api网关url通过查询字符串传递表单数据,并使用后端python lambda函数发送邮件。如果我在表格中添加谷歌验证码。如何通过用户在google Captcha中输入的api网关url中的查询字符串传递数据您不返回用户输入的查询字符串。谷歌API将为您进行验证,并为您提供用户响应令牌。这是由reCAPTCHA提供的,用于验证站点上的用户。将其发送给lambda,并从他们那里验证此响应是否正确-谢谢你,我终于用aws lambda完成了验证google验证码的任务,这非常有用。谢谢你一次收获
'use strict';
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var reCAPTCHA = require('recaptcha2')
var fs = require('fs');
var Handlebars = require('handlebars');
module.exports.sendemail = (event, context, callback) => {
// parse the data that was sent from API Gateway
var eventData = JSON.parse(event.body);
// Prepare the recaptcha connection to Google
var recaptcha = new reCAPTCHA({
siteKey: process.env.RECAPTCHA_KEY,
secretKey: process.env.RECAPTCHA_SECRET
})
// Validate the recaptcha value
recaptcha.validate(eventData.recaptcha)
.then(function(){
// validated ok
console.log("reCAPTCHA Valid")
// Read the HTML template from the package root
fs.readFile('./contact/email_template.html', function (err, emailHtmlTemplate) {
if (err) {
console.log("Unable to load HTML Template");
throw err;
}
// Read the TEXT template from the package root
fs.readFile('./contact/email_template.txt', function (err, emailTextTemplate) {
if (err) {
console.log("Unable to load TEXT Template");
throw err;
}
// Gather data to be injected to the templates
var emailData = {
"websiteaddress": process.env.WEBSITEADDRESS,
"websitename": process.env.WEBSITENAME,
"content": null,
"email": process.env.EMAIL_TO,
"event": eventData
};
// Use Handlebars to compile the template and inject values into the title (used in subject and body of email)
var templateTitle = Handlebars.compile(process.env.EMAIL_TITLE);
var titleText = templateTitle(emailData);
console.log(titleText);
// Add title to the values object
emailData.title = titleText;
// Use Handlebars to compile email plaintext body
var templateText = Handlebars.compile(emailTextTemplate.toString());
var bodyText = templateText(emailData);
console.log(bodyText);
// Use Handlebars to compile email html body
var templateHtml = Handlebars.compile(emailHtmlTemplate.toString());
var bodyHtml = templateHtml(emailData);
console.log(bodyHtml);
// Prepare the SES payload
var params = {
Destination: {
ToAddresses: [
process.env.EMAIL_TO
]
},
Message: {
Body: {
Text: {
Data: bodyText,
Charset: 'UTF-8'
},
Html: {
Data: bodyHtml
},
},
Subject: {
Data: titleText,
Charset: 'UTF-8'
}
},
Source: process.env.EMAIL_FROM
}
console.log(JSON.stringify(params,null,4));
// Send SES Email
ses.sendEmail(params, function(err,data){
if(err) {
console.log(err,err.stack); // error
// Handle SES send errors
var response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Error: Unable to Send Message"})
}
callback(null, response);
}
else {
console.log(data); // success
// SES send was successful
var response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Message Sent"})
}
callback(null, response);
}
});
}); //end of load text template
}); //end of load html template
})
.catch(function(errorCodes){
// invalid recaptcha
console.log("reCAPTCHA Not Valid")
// translate error codes to human readable text
console.log(recaptcha.translateErrors(errorCodes));
// send a fail message with cors headers back to the UI
var response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Error: Invalid Recaptcha"})
}
callback(null, response);
});
};