
用 Azure Static Web Apps 部署 IoT 位置可视化应用将 subscriptionKey 安全托管到云端【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本指南以IoT-For-Beginners项目第三模块交通 / Transport第 3 课《可视化位置数据》的课后作业为核心讲解如何把课程中构建的、基于 Azure Maps 的 GPS 位置数据可视化 Web 应用部署到云端并利用 Azure Static Web Apps 的能力将原本写死在页面里的subscriptionKey重构为云端的变量存储。读完本文你将掌握静态 Web 应用的云端部署流程、API 密钥的云端托管与安全重构思路以及如何对照作业评估标准自检交付质量。作业是什么把可视化应用从本地搬到云端在 3-transport/lessons/3-visualize-location-data/README.md 这一课中你已经完成了从 GPS 传感器采集位置、经 IoT Hub 与 Azure Functions 写入 Blob 存储、再到在网页上通过 Azure Maps 展示行驶路径的完整链路。而 作业原文保加利亚语翻译 与 英文作业原文 提出的要求是有若干种方式可以将你的应用部署出去与全世界分享包括使用 GitHub Pages 或众多服务提供商之一。一个真正优秀的方式是使用Azure Static Web Apps。在本作业中构建你的 Web 应用并按照官方说明或视频教程将其部署到云端。 使用 Azure Static Web Apps 的一个好处是你可以在门户中隐藏所有 API 密钥因此请借此机会将你的subscriptionKey重构为一个变量并把它存储在云端。也就是说这份作业有两条主线部署把上一课做好的、仅在本机运行的index.html静态应用部署到 Azure Static Web Apps获得一个可公开访问的线上地址安全重构把当前硬编码在 JavaScript 里的 Azure MapssubscriptionKey从客户端代码中剥离改为从云端变量应用设置 / Application Settings读取。先看清你要部署的应用长什么样部署不是把文件随手一传首先要理解这份静态应用的组成。课程提供了一份完整的单文件应用 code/index.html其工作流程如下页面加载时通过body onloadinit()触发init()init()用fetch请求 Blob 容器的 XML 列表接口https://storage_name.blob.core.windows.net/gps-data/?restypecontainercomplist拿到容器内所有 blob 的Url对每个 blob 调用loadJSON()通过XMLHttpRequest读取 JSON 内容解析出gps.lon/gps.lat并构造成atlas.data.Feature创建atlas.Map实例并在ready事件中用atlas.source.DataSource与atlas.layer.BubbleLayer把 GPS 点以气泡图层绘制在地图上。核心代码如下来自 code/index.htmlfunction init() { fetch(https://storage_name.blob.core.windows.net/gps-data/?restypecontainercomplist) .then(response response.text()) .then(str new window.DOMParser().parseFromString(str, text/xml)) .then(xml { let blobList Array.from(xml.querySelectorAll(Url)); blobList.forEach(async blobUrl { loadJSON(blobUrl.innerHTML) }); }) .then(response { map new atlas.Map(myMap, { center: [-122.26473, 47.73444], zoom: 14, authOptions: { authType: subscriptionKey, subscriptionKey: subscription_key, } }); map.events.add(ready, function () { var source new atlas.source.DataSource(); map.sources.add(source); map.layers.add(new atlas.layer.BubbleLayer(source)); source.add(features); }) }) } var map, features; function loadJSON(file) { var xhr new XMLHttpRequest(); features []; xhr.onreadystatechange function () { if (xhr.readyState XMLHttpRequest.DONE) { if (xhr.status 200) { gps JSON.parse(xhr.responseText) features.push( new atlas.data.Feature(new atlas.data.Point([parseFloat(gps.gps.lon), parseFloat(gps.gps.lat)])) ) } } }; xhr.open(GET, file, true); xhr.send(); }注意其中的两个占位符storage_name存储账户名与subscription_keyAzure Maps 的 API 密钥。前者在本机运行时已可正常工作后者正是本作业要求重点重构的对象——因为subscription_key一旦随静态文件部署上线就等于把密钥明文暴露给了所有访问者。页面头部还引入了 Azure Maps Web SDK 的控制组件样式与脚本这份静态页面在浏览器中的最终效果类似下图——地图聚焦西雅图地区部署前必须完成的三项前置条件作业是建立在第 2 课《存储位置数据》已完成的云端资源之上的部署前请确认以下几点详见 3-transport/lessons/2-store-location-data/README.md1. Azure Maps 资源与密钥已就绪第 3 课要求先创建 Azure Maps 资源并取得 API 密钥az maps account create --name gps-sensor \ --resource-group gps-sensor \ --accept-tos \ --sku S1 az maps account keys list --name gps-sensor \ --resource-group gps-sensor \ --output table其中S1是付费层级包含一系列功能且附带慷慨的免费调用额度az maps account keys list输出的PrimaryKey即页面中使用的subscriptionKey。2. Blob 存储已开启 CORS 且容器可公开读取第 2 课在创建gps-data容器时get_or_create_container函数使用了public_accessPublicAccess.Container见 3-transport/lessons/2-store-location-data/code/functions/gps-trigger/iot-hub-trigger/init.py允许公开查询容器中的 blob。同时为了让部署在云端不同源的页面能够直接读取 blob 数据还需为存储账户开启 CORSaz storage cors add --methods GET \ --origins * \ --services b \ --account-name storage_name \ --account-key key1--services b表示仅对 Blob 服务生效--origins *表示允许任意来源发起 GET 请求。若跳过此步浏览器控制台会出现跨域读取错误页面将无法加载 GPS 数据。3. 本地能通过 http-server 正常预览课程建议本地开发时使用http-server需先安装 Node.js 与 npm。在index.html所在目录执行http-server应用会在本机 Web 服务器 http://127.0.0.1:8080/ 上打开。本地验证通过是部署的前提——如果本机都渲染不出地图与气泡部署后只会把问题带到线上。部署方案选型为什么作业推荐 Azure Static Web Apps作业明确指出部署方式并不唯一可以使用 GitHub Pages也可以使用众多服务提供商之一而 Azure Static Web Apps 是其中真正优秀的方式。从该应用的实际构成看这份交付物是一个纯前端静态站点一个 HTML 文件 Azure Maps Web SDK而 Azure Static Web Apps 正是为这类静态 Web 应用设计的托管服务它的优势与本作业诉求高度契合开箱即用的全球 CDN 与免费 HTTPS部署后立即获得一个可公开访问、可通过浏览器分享的线上地址与 Git 仓库及 CLI 深度集成支持自动化构建与部署对应作业评估标准中的在文档化的 GitHub 仓库中交付门户中的应用设置Application Settings可以在云端集中存放密钥不必把敏感信息写入前端代码——这正是本作业要求隐藏subscriptionKey的落点天然支持将前端与 Azure Functions 后端 API 组合部署为把密钥藏到云端提供了服务端承载空间。通过 Azure Static Web Apps CLI 完成部署作业要求按照官方 static-web-apps-cli 说明或配套视频操作。基于该工具的标准工作流典型部署步骤大致如下具体参数请以作业中引用的官方说明为准初始化项目结构把课程提供的index.html放入一个独立目录例如app/或wwwroot/该目录即后续的应用位置app location。安装并初始化 SWA CLInpm install -g azure/static-web-apps-cli swa initswa init会引导你配置应用位置、API 位置本作业无后端时可留空等信息并生成部署配置。本地模拟生产环境可选但推荐swa start这会在本地模拟 Static Web Apps 的运行时用于上线前复现线上环境行为。登录并部署swa login swa deploy ./app_location --env production部署完成后CLI 会输出一个形如https://app-name.region.azurestaticapps.net的线上地址。你也可以选择把仓库托管到 Git 平台并与 Azure Static Web Apps 关联实现推送到主干分支即自动构建发布从而满足评估标准中文档化的 GitHub 仓库这一交付形式。安全重构把 subscriptionKey 从客户端代码迁移到云端这是本作业除部署外的第二个硬性要求也是它与普通上传静态文件练习拉开差距的关键点。原页面中的密钥以明文写死在authOptions里authOptions: { authType: subscriptionKey, subscriptionKey: subscription_key, }任何打开部署后页面的人都能通过查看源代码直接拿到你的 Azure Maps 密钥密钥随之面临被滥用、超量调用产生费用甚至被封禁的风险。重构目标是把subscription_key替换为一个变量引用而变量真正的值只存在于云端如 Static Web Apps 门户的 Application Settings。作业强调的在门户中隐藏 API 密钥将其存储为变量在 Azure Static Web Apps 体系中有几种常见落地路径应用设置Application Settings在 Azure Static Web Apps 门户的配置中新增一条应用设置例如AZURE_MAPS_KEY值填你的 PrimaryKey。前端代码通过构建期或运行期的变量注入机制读取它而不是硬编码。具体注入方式取决于你的前端工具链是否具备构建期环境变量替换能力如常见的 Vite / Webpack 等框架化构建流程会支持import.meta.env之类的变量注入。服务端代理 / API 路由由于本作业是一个纯 HTML/JS 应用没有打包器参与变量替换更稳妥的做法是借助 Static Web Apps 附带的 Azure Functions 后端由 Functions 读取应用设置中的密钥前端通过调用自己的 API 路由间接获取密钥或让服务端代为拼接地图请求保证密钥永不进入浏览器源码。这也是把密钥藏在云端、客户端只保留变量引用的最彻底形态。无论采取哪种路径最终交付的init()中都不应再出现明文密钥而是形如authOptions: { authType: subscriptionKey, subscriptionKey: AZURE_MAPS_KEY, // 从云端变量读取而非硬编码 }需要说明的是把纯静态页面做到运行期密钥完全不可见通常需要引入一个最小的服务端函数层具体的变量注入语法与 API 路由配置应以你采用的工具链和官方文档为准。对照评估标准自检交付质量作业提供了一张评估表Rubric这是验收的核心依据原文如下译自 assignment.md标准优秀Exemplary达标Adequate需改进Needs Improvement整体交付在一个文档化的 GitHub 仓库中交付可运行的 Web 应用subscriptionKey已存储在云端并通过变量调用在一个文档化的 GitHub 仓库中交付可运行的 Web 应用但subscriptionKey未存储在云端Web 应用存在 Bug 或无法正常运行对照此表完成作业前请逐一确认可运行性部署后的线上地址能正常加载 Azure Maps能读取gps-data容器中的 GPS 数据并绘制气泡轨迹浏览器控制台无 CORS 或 404 报错文档化仓库应用代码保存在带说明文档的 Git 仓库中README 至少说明应用是什么、如何本地运行、如何部署密钥云端化优秀档的关键分水岭仓库与部署产物中均搜不到明文subscriptionKey代码中只剩变量引用真实密钥值只存在于云端应用设置中。第 3 点正是优秀与达标的唯一区别——应用能跑且仓库有文档只是及格线把密钥搬进云端才算拿到优秀档。小结与排查提示本作业把第 2 课、第 3 课的所有成果串联为一个可对外分享的交付物一个能实时可视化 GPS 行驶轨迹、且不在客户端暴露密钥的云端 Web 应用。部署链路为index.htmlAzure Maps Web SDK→ Azure Static Web AppsCDN 应用设置→ Blob 存储gps-data容器已开 CORS→ IoT Hub / Functions数据源。若部署后遇到问题可按以下顺序排查地图空白、控制台报401/403检查subscriptionKey变量是否真正读到了云端设置的值地图能显示但无气泡多半是 CORS 未配置回到az storage cors add步骤检查--services b与--origins参数fetch列表接口返回空确认storage_name占位符已被替换为实际存储账户名且容器名确实是gps-data与 第 2 课函数代码 中get_or_create_container(gps-data)保持一致。至此你就完成了一次静态应用部署 密钥安全托管的完整实战这也是 IoT 项目中把本地原型推向真实世界的基础能力。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考