如何为返回HTML页面的AWS Lambda函数添加认证保护?
解决AWS REST API中show-data端点的Token暴露安全问题
核心问题分析
当前架构中,show-data端点返回的HTML页面直接在AJAX配置中携带Bearer Token,导致Token在页面源码、浏览器开发者工具的网络请求中完全暴露。即使get-data已配置Token授权,未授权用户仍可通过访问show-data获取Token,进而调用get-data接口,同时show-data本身也处于无保护状态。
可行解决方案
方案1:为show-data端点添加Lambda Authorizer
直接复用get-data已配置的Token验证Lambda Authorizer,给show-data的GET方法开启授权校验:
- 在API Gateway控制台找到
show-data资源的GET方法,进入「授权」配置项,关联已有的Lambda Authorizer - 设置Token来源为请求头的
Authorization字段,要求访问show-data的请求必须携带合法Bearer Token - 效果:未授权用户无法获取到包含AJAX逻辑的HTML页面,从源头阻断Token泄露的可能
方案2:移除HTML中的硬编码Token,改用前端认证状态注入
彻底不在后端返回的HTML中写死Token,让前端从自身的认证存储中读取Token:
- 调整
show-data的Lambda返回的HTML代码,修改AJAX的授权头配置:// index.html中的AJAX代码修改示例 $(document).ready(function() { // 从本地存储读取Token(前提是用户已通过独立登录流程存入) const authToken = localStorage.getItem('authToken'); if (!authToken) { window.location.href = '/login'; // 无Token时跳转登录页 return; } $.ajax({ url: "{{API_URL}}/{{API_STAGE}}/get-data", type: "POST", headers: { "Authorization": `Bearer ${authToken}` }, success: function(data) { $('#dataTable').DataTable({ data: data, columns: [/* 你的列定义 */] }); } }); }); - 配套要求:用户需先通过独立认证流程(比如Cognito登录)获取Token并存入本地存储,再访问
show-data页面
方案3:改为后端代理模式,完全隐藏Token交互
把show-data的Lambda改为后端代理,直接在AWS内部调用get-data接口,再将数据与HTML模板结合后返回:
- 给
show-data的Lambda分配IAM角色,允许其调用get-data所在的API Gateway(无需Bearer Token,通过IAM权限控制) - Lambda内部逻辑调整:调用
get-data获取数据,填充到HTML模板后返回渲染完成的页面,前端无需再发起AJAX请求 - 效果:前端完全接触不到Token,所有敏感交互都在AWS服务间完成,彻底避免Token暴露
方案4:使用Cognito原生身份管理替代自定义Token
集成Amazon Cognito用户池+身份池,实现标准化的安全Token管理:
- 用Cognito托管UI完成用户登录,前端通过AWS Amplify库自动获取临时AWS凭证
- 配置API Gateway使用Cognito Authorizer,前端调用API时自动使用SigV4签名认证,无需手动配置Bearer Token
- 优势:利用AWS原生身份管理机制,自动处理Token的刷新、过期等问题,大幅降低安全风险
调整后的show-data Lambda代码示例(方案2)
exports.handler = async (event) => { const htmlContent = ` <!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.css"> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.js"></script> </head> <body> <table id="dataTable"></table> <script> $(document).ready(function() { const authToken = localStorage.getItem('authToken'); if (!authToken) { window.location.href = '/login'; return; } $.ajax({ url: "${process.env.API_URL}/${process.env.API_STAGE}/get-data", type: "POST", headers: { "Authorization": "Bearer " + authToken }, success: function(data) { $('#dataTable').DataTable({ data: data, columns: [ { title: "ID" }, { title: "名称" } ] }); } }); }); </script> </body> </html> `; return { statusCode: 200, headers: { "Content-Type": "text/html" }, body: htmlContent }; };
内容的提问来源于stack exchange,提问作者Chirag Arora
相关产品推荐
相关产品推荐

