使用 AWS Serverless 创建简单的 OTP 系统
简介
这篇文章介绍了如何使用 AWS 无服务器服务实现一个简单的一次性密码 (OTP) 系统,该系统可用作两步验证的一部分。
以下是构建此应用程序所使用的工具和技术。
建筑学
工作原理
-
在这种情况下,我使用了一个登录表单,它是用 VueJS 开发的,并使用 Amplify 静态网络托管来托管。
-
用户将输入他们的电子邮件和密码,一旦凭证得到验证,就会调用 API 端点来执行“生成 OTP”Lambda 函数,该函数会生成一个 6 位数的代码以及一个会话 ID。
-
一旦生成代码和会话 ID,“生成 OTP”Lambda 就会将这些数据保存到 DynamoDB 表中。
-
然后,只有会话 ID 会作为 API 端点的响应返回。
-
表中已启用 DynamoDB 流。因此,一旦数据保存完毕,它将触发“发送电子邮件”Lambda 函数。
-
在“发送电子邮件”Lambda 函数中,它将调用简单电子邮件服务 (SES) 将包含生成代码的电子邮件发送到提供的电子邮件地址。
-
同时,在前端,一旦从 API 接收到会话 ID,就会显示第二个表单来输入代码,该代码将通过电子邮件发送到给定的地址。
-
一旦用户输入代码并提交,它将使用代理“验证 OTP”Lambda 函数的另一个 API 网关端点验证代码和会话 ID。
-
在“验证 OTP”Lambda 函数中,它使用给定的会话 ID 和代码查询 DynamoDB 表并返回成功或错误响应。
要点/经验教训
-
这里我启用了 DynamoDB TTL,以便在特定时间后删除条目,以防止表格过快填满。但是,当 TTL 过期时,DynamoDB 不会立即删除您的记录。它最终会被删除,并且 AWS 仅保证在 48 小时内删除。因此,在验证 OTP 代码时,必须考虑用于设置 TTL 的相同“expiredAt”字段。
-
在设计 DynamoDB 表时,我使用 sessionId + OTP 代码作为主键,以便轻松查询所需的记录。因此,在验证代码时,我在 DynamoDB 表中使用此组合通过主键进行查询。
-
当使用 DynamoDB Stream 作为 Lambda 的触发器时,它会获取所有 DynamoDB 事件(例如:插入、删除、更新)的触发器。因此,在 Lambda 函数中,必须仅使用记录的“eventName”过滤掉INSERT事件。
-
为了发送电子邮件,我使用了 AWS 自己的简单电子邮件服务 (SES)。但是,您需要先验证您的发送电子邮件地址才能向任何地址发送电子邮件。这可以通过提交支持请求来完成。
-
在这里,我使用了 Amplify 静态 Web 托管来托管应用程序的前端。我使用了 Amplify 的功能——当 Github 仓库修改时自动部署,以及只需点击几下按钮即可设置自定义域名。
-
我已经使用 AWS SAM 部署了后端资源。可以在部署时配置 OTP 的到期时间和 OTP 代码中的位数。
如何设置
先决条件
- AWS CLI
- AWS SAM CLI
- 设置并验证 SES 发送电子邮件地址
后端
sam init && sam deploy -g
After providing your stack information and AWS environment parameters, this will create the backend stack. Copy the ApiBaseUrl output value.
#### Frontend
1. Copy the .env.example into .env file and add the ApiBaseUrl value as *VUE_APP_API_BASE_URL*.
2. You may zip the whole frontend directory and use that in Amplify web hosting, or authorize your GitHub repository to automatically deploy the application when a git push is made.
3. If you need to run the frontend in local, navigate to frontend directory and run `npm run serve`
#### To Delete the stack
To remove the backend, run `sam delete`.
## Demo
Demo version of this application is available at :
[https://simple-otp.pubudu.dev/](https://simple-otp.pubudu.dev/)
## Feedback
Your valuable feedback on this project is mostly welcome! I would like you to play around with this and if you have any questions or general comments, please reach out to me via [Personal Blog](https://pubudu.dev), [LinkedIn](https://www.linkedin.com/in/pubudusj/), [Twitter](https://twitter.com/pubudusj) or [Github](https://github.com/pubudusj).
Keep building, keep sharing!