英文:
Implementing an email database from a website form
问题 {#heading}
我希望我的网站访客能够在表单中提供他们的电子邮件地址,以获取未来公司的更新。一旦他们提交表单,将会向他们的电子邮件地址发送一封电子邮件,其中包含一个链接,点击链接后,链接将指向 www.mywebsite.com/<token>
。访问该链接后,他们的电子邮件将得到验证,并成为我用来发送更新的数据库的一部分。
我打算使用 AWS S3、AWS CloudFront 和 AWS Certificate Manager 部署我的网站。对于电子邮件验证流程的实现:当用户提交表单时,将通过 API Gateway 触发一个 Lambda 函数,在该函数中生成令牌,并通过调用 AWS SES 向访客发送电子邮件。
在这个框架内,我遇到了一个问题,即如何动态创建和提供 www.mywebsite.com/<token>
形式的URL。我可以看到,如果后端有一个运行中的服务器,可以通过以下方式实现:
const express = require('express')
const app = express()
app.get('/verify-email/:token', async (req, res) => {
const token = req.params.token;
// 检查令牌
// 如果匹配,验证电子邮件,添加到数据库,并渲染页面
// 如果不匹配,重定向
});
在我上面详述的S3框架内,我该如何创建和提供这些URL呢?
是否需要改变实现方式,而改用 EC2 服务器或其他 AWS 服务? 英文:
I want visitors of my website to be able to provide their email address in a form to get future company updates. Once they submit the form an email would be sent to their address with a link to click on, say www.mywebsite.com/<token>
. Upon visiting that link their email would be validated and become part of the database I would use to send updates.
I have in mind deploying my website using AWS S3 together with AWS CloudFront and AWS Certificate Manager. For the implementation of the email verification process: a Lambda function would be triggered through API Gateway when a user submits the form, the token would be generated in that function, and an email would be sent to the visitor with a call to AWS SES.
I'm having issue understanding within that framework how I can create dynamically and serve URLs of the form www.mywebsite.com/<token>
. I can see that with a server up and running in the backend, this could be achieved with something along the lines of
const express = require('express')
const app = express()
`app.get('/verify-email/:token', async (req, res) => {
const token = req.params.token;
// check token
// if match, validate email, add to database, and render page
// if no match, redirect
});
`
How can I create and serve these URLs within the S3 framework I detailed above?
Do I need otherwise to change the implementation and run instead an EC2 server or use another AWS service?
答案1 {#1}
得分: 1
你现在走在正确的道路上。API网关/ Lambda非常适合这个任务。关于"我如何在我上面详细描述的S3框架内创建和提供这些URL?"这句话的含义不太清楚,因为你提到在网关中创建它们,但我认为你是在说用户点击电子邮件中的链接后会发生什么。
你可以在API网关中创建一个GET路由 - 这个路由需要是公开可访问的(无需身份验证)。Lambda可以验证令牌(使用JWT令牌,因为它们就是为这个目的而制作的),然后将重定向发送到S3站点上的感谢页面。
或者,你可以让S3站点处理令牌路由,然后让它调用服务器来处理并返回成功/失败。这在例如使用React站点时会很好地运行。
为了处理前端的<token>
路由,你可以使用框架内置的一些实用工具(例如,如果你使用NextJS,可以使用useParams()
),或者使用JS/JQuery来解析路径。你只会有一个页面 - 即index.html - 它将处理所有这些。这在你的S3配置中定义。这意味着无论你输入什么URL(domain.com、domain.com/sometoken、domain.com/contact等),index.html都会呈现,由JS(原生、JQuery、React)来解析路径并确定下一步该做什么。如果你打算有其他页面,比如contact
,那么我建议使用类似/auth/<token>
的路径来帮助区分令牌URL和其他页面。
顺便说一下,你可以让API网关上的单个Lambda运行一个Express应用程序,使用类似这个的NodeJS库。
另外一点,Lambda有函数URL,这可能会很有用 - 它们不提供网关提供的身份验证/限流等功能,也不能更改域名/URL,但在第二种情况下可以很好地工作。 英文:
You're on the right track. API Gateway/Lambda is perfect for this. It's not clear what you mean by "How can I create and serve these URLs within the S3 framework I detailed above?" since you mentioned creating these in the gateway but I assume you refer to what happens once the user clicks the link in their email.
You can either create a GET route in the API gateway - this route will need to be publicly accessible (no auth). The Lambda can verify token (use JWT tokens for this as they are made for just this) and then send a redirect to say a thank you page on your S3 site.
Alternatively you can have the S3 site handle that token route, then have it make a call to the server to process and return a success/fail. This would work well for example with a React site.
In order to handle the <token>
route on front end you would either use some of the built-in utilities your framework would have (for example if you used NextJS then useParams()
) or use JS/JQuery to parse the path. You will only have a single page - i.e. index.html - that will handle all of this. This is defined in your S3 config. Meaning no matter what URL you type (domain.com, domain.com/sometoken , domain.com/contact, etc) the index.html will render and it's up to JS (native, JQuery, React) to parse the path and determine what to do next. If you intend to have other pages such as contact
then Id recommend using something like /auth/<token>
in order to help differentiate token URLS from the other pages.
On a side note, you can have a single Lambda on API gateway run an Express app using some libs such as this for NodeJS.
On an additional side note, Lambdas have Function URLs which can be useful - they do not provide auth/throttling etc that the gateway does nor can you change the domain/URL but would work well for the 2nd scenario.