安全的地图 API 身份验证设计会按运行环境分离凭据。浏览器需要可以公开、但严格限制在获批来源和能力范围内的凭据;后端需要永不进入客户端代码、可授权服务器间操作的秘密凭据。二者不能互换。应限制作用域、分离环境、监控用量、轮换凭据,并区分身份验证失败与授权失败。Kaleidr 通过可发布浏览器密钥 (kld_pk_live_…) 和服务器密钥 (kld_sk_live_…) 实现这一模式。
下文介绍浏览器与服务器凭据、来源、CORS、作用域、生命周期、多租户信任边界和常见错误。相关信息请参阅开发者文档。SDK 架构请参阅什么是 AI 地图 SDK?,嵌入和聊天挂载请参阅如何嵌入交互式地图以及在 Mapbox、Google Maps 和 MapLibre 上添加 AI 聊天。
身份验证要点
- 先考虑运行环境: 浏览器凭据为可公开而设计,服务器凭据为保密而设计。
- 来源 ≠ 身份验证: CORS 和允许来源不能替代凭据检查。
- 作用域 ≠ 租户: API 能力作用域不等于应用用户或数据行授权。
- 安全轮换: 撤销有效密钥前先部署替代密钥。
- 日志脱敏: 记录密钥 ID 和状态码,绝不记录凭据值。

为什么浏览器中的地图 API 身份验证不同?
浏览器是不受信任的运行环境。发送给浏览器的内容通常都能通过页面源代码、开发者工具、网络请求、打包后的 JavaScript、浏览器存储或运行时对象检查。在客户端代码中放置长期服务器机密——包括 React 源码、Next.js NEXT_PUBLIC_*、Vite VITE_*、HTML、移动 WebView 或前端 JSON——并不安全,因为浏览器无法向运行它的人隐藏机密。应询问凭据允许做什么、允许在哪里运行,而不是如何把密钥藏进前端包。
| 属性 | 可发布/浏览器凭据 | 服务器凭据 |
|---|---|---|
| 预期环境 | 浏览器或客户端 SDK | 受信任后端 |
| 在客户端可见 | 可能 | 绝不 |
| 安全模型 | 受限能力 + 获批来源 + 短期会话(如支持) | 秘密 bearer 凭据 |
| 主要风险 | 未授权复用或配额滥用 | 账户或数据泄露 |
不同平台名称不同,但模式相同。Kaleidr 使用可发布密钥和服务器密钥(Auth & Scopes)。Mapbox 区分公开与秘密令牌作用域,并要求秘密令牌请求从服务器发出(安全使用 Mapbox)。Google Maps Platform 使用应用和 API 限制,并建议保护 Web 服务凭据;服务器间访问在支持时使用 OAuth 2.0(安全指南)。客户端凭据应为公开而设计,服务器凭据应为保密而设计。
Kaleidr 可发布密钥和服务器密钥如何工作?
当前文档为同一组织和能力系统定义两种密钥。可发布密钥以 kld_pk_live_… 开头,用于 HTML、Kaleidr SDK、<kaleidr-map> 和浏览器集成。SDK 在运行时将其换成与来源绑定的短期会话,而不是把字符串作为长期 bearer 凭据。服务器密钥以 kld_sk_live_… 开头,仅用于受信任服务器,通常放在 Authorization: Bearer … 或 X-Api-Key: … 中。服务器密钥会被浏览器阻止,也不会获得 CORS 授权(CORS & Allowed Origins)。绝不要把服务器密钥放进客户端,也不要把公开前端环境变量当作秘密存储。
允许来源必须是没有路径和尾随斜杠的纯来源,例如 https://app.example.com,不能是 https://app.example.com/maps。除 localhost 或 127.0.0.1 本地测试外,Kaleidr 目前要求 HTTPS。来源必须精确匹配:根域、www、app、admin 和预览主机是不同来源。来源限制可减少浏览器中的未授权复用,但不能替代把服务器机密留在客户端之外。
CORS、身份验证、作用域和应用授权有何不同?
CORS 控制浏览器能否读取跨来源响应;身份验证识别调用方;作用域授权判断凭据能否使用某项能力;宿主后端负责的应用授权决定哪个用户或租户可以访问私有记录。Kaleidr 的 CORS 流程可以允许预检,但仅在来源获批时返回 Access-Control-Allow-Origin;服务器密钥没有浏览器 CORS 授权。401 通常表示凭据缺失、无效、过期或已撤销;403 通常表示凭据有效但权限不足。Kaleidr 在密钥有效但缺少路由所需能力时使用 insufficient_scope。诊断和监控时应将它们视为不同故障。

应如何创建、存储、轮换和撤销凭据?
应用最小权限,只授予每项集成所需作用域。Mapbox 建议把令牌作用域限制到最小,并在浏览器中只使用公开作用域;Google 同样建议同时使用应用限制和仅覆盖实际 API 的 API 限制。不要让所有环境共享一个凭据,应分开开发、预览和生产密钥,以缩小影响范围并简化轮换。Mapbox 建议按环境或客户端使用不同令牌;Google 建议每个应用使用不同 API 密钥(令牌管理)。
新创建的 Kaleidr 密钥值只显示一次,应立即复制到机密管理器。服务器密钥应存储在机密管理器或受保护的服务器环境中,绝不能进入公开仓库或浏览器包。CI/CD 应在部署时注入机密,在日志中遮蔽,并避免输出环境转储。只记录密钥 ID、请求状态和来源;对授权标头与凭据值脱敏。轮换时先创建替代密钥并配置限制,部署后验证流量,最后撤销旧密钥;若旧密钥已泄露则应加速。配额也是安全控制:Platform API 按组织计量,流式端点限制并发(Quota & Rate Limits)。429 应与 401、403 分开处理,采用退避而不是重试风暴。
// Unsafe: never ship a server key to the browser
const SERVER_KEY = "YOUR_KALEIDR_SERVER_KEY";
// Safer browser pattern: publishable key + SDK session exchange
Kaleidr.mount("#map", {
publishableKey: "kld_pk_live_REPLACE_ME"
});
// Safer backend pattern: server key stays on the host
const response = await fetch("https://api.example.com/resource", {
headers: {
Authorization: `Bearer ${process.env.KALEIDR_SERVER_KEY}`
}
});

生产应用应如何分离平台身份验证与宿主身份验证?
推荐模式让浏览器通过获批来源和可发布密钥使用公开 SDK 地图功能,而已验证的产品请求发送到宿主后端。后端管理用户身份、租户成员资格、对象授权、私有位置数据及机密管理器中的服务器密钥,再发起服务器间空间平台调用并只返回获批字段。可发布密钥不是最终用户身份验证,服务器密钥也不是数据库行授权。Kaleidr 当前文档称,已发布 Viewer 地图由分享链接控制,无需 API 密钥;仍应把分享链接视为访问控制,并避免通过不受限公共视图发送私有数据。CSP 和安全 HTML 渲染是补充控制;Mapbox 警告,在弹窗中注入不受信任 HTML 会造成 XSS 风险,并建议对不受信任内容使用文本渲染。

团队应避免哪些错误?
| 错误 | 风险 | 更好的方法 |
|---|---|---|
| 在 JavaScript 中发送服务器密钥 | 凭据被盗 | 使用可发布密钥或后端代理 |
| 把 CORS 当成身份验证 | 非浏览器调用方绕过假设 | 验证每个受保护请求 |
| 到处使用同一密钥 | 影响范围很大 | 分离环境和应用 |
| 给每个密钥全部作用域 | 权限过大 | 应用最小权限 |
| 在来源白名单中添加路径 | 来源匹配失败 | 使用 scheme://host[:port] |
| 记录授权标头 | 机密泄露到日志 | 对凭据脱敏 |
| 把可发布密钥当作用户身份 | 用户无法区分 | 使用真正的最终用户验证 |
| 认为 API 验证可保护私有数据行 | 租户数据可能泄露 | 应用宿主授权 |
| 未检查流量就轮换 | 生产中断 | 撤销旧密钥前部署替代项 |
| 忽略 429 | 重试风暴和糟糕体验 | 退避并监控配额 |
浏览器集成失败时,先检查来源拼写、HTTPS 要求、密钥类型、作用域和会话交换顺序,再判断平台故障。服务器集成失败时,检查密钥类型、环境、作用域、机密注入及轮换期间是否误撤销。
最终结论
地图 API 安全始于一项架构决定:浏览器和后端不能使用相同的凭据模型。浏览器需要可公开、受来源、作用域、会话期限或等效控制约束的凭据;后端需要留在受信任基础设施中的机密。再叠加最小权限、环境隔离、应用授权、监控和轮换。Kaleidr 当前模型直接遵循这一模式:浏览器密钥受来源限制,并由 SDK 换成短期会话;服务器密钥是用于服务器间调用的 bearer 凭据,并被浏览器阻止。这条边界比试图把密钥藏在前端代码中更重要。
使用 Kaleidr 文档保护地图 API
部署前请检查当前密钥类型、能力作用域、来源规则和 API 行为。阅读 Kaleidr Auth & Scopes,然后在开发者文档中继续了解 SDK 挂载和 Platform API 路由。
常见问题
什么是地图 API 身份验证?
它是识别请求访问地图、地点、瓦片、路线或空间 API 的应用或服务的机制。常见机制包括 API 密钥、访问令牌、会话、bearer 令牌和 OAuth。
API 密钥能否安全用于浏览器?
只有提供方专门为客户端设计时才可以。浏览器安全密钥应受允许来源、公开作用域、应用限制或短期会话交换等约束。服务器机密绝不能放入浏览器代码。
可发布 API 密钥是机密吗?
不是。其安全性不应依赖字符串保持隐藏,但仍需限制和监控。
服务器 API 密钥是机密吗?
是。它应留在受信任后端中,不能出现在 HTML、JavaScript 包、移动 WebView、公开仓库或客户端存储中。
CORS 是身份验证吗?
不是。CORS 控制浏览器能否读取跨来源响应;身份验证识别调用方;授权决定调用方能做什么。
401 和 403 有何区别?
401 通常表示凭据缺失、无效、过期或已撤销。403 通常表示凭据有效,但无权执行所请求操作。
开发和生产应使用不同 API 密钥吗?
是。分离凭据可缩小影响范围、简化来源限制、提高用量可见性并使轮换更安全。
应如何轮换 API 密钥?
创建替代密钥、配置限制、部署并验证生产流量,然后再撤销旧密钥。若旧密钥正遭泄露,应加速处理。
Kaleidr Viewer 需要 API 密钥吗?
当前文档称,已发布 Viewer 地图受分享链接控制,不需要 API 密钥。
Kaleidr 如何保护浏览器集成?
当前模型使用带允许来源列表的可发布密钥。SDK 将其换成与来源绑定的短期会话。服务器密钥会被浏览器阻止,仅用于服务器间调用。
参考资料
IETF. HTTP Semantics (RFC 9110). RFC Editor. 查阅于 2026年8月17日. https://www.rfc-editor.org/rfc/rfc9110
IETF. The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750). RFC Editor. 查阅于 2026年8月17日. https://www.rfc-editor.org/rfc/rfc6750
WHATWG. Fetch Standard. 查阅于 2026年8月17日. https://fetch.spec.whatwg.org/#http-cors-protocol
Google。Google Maps Platform 安全指南。Google Maps Platform 文档。访问日期:2026年8月17日。https://developers.google.com/maps/api-security-best-practices
Kaleidr。Auth & Scopes。Kaleidr 开发者文档。访问日期:2026年8月17日。https://docs.kaleidr.com/platform-api/auth-and-scopes
Kaleidr。CORS & Allowed Origins。Kaleidr 开发者文档。访问日期:2026年8月17日。https://docs.kaleidr.com/platform-api/cors-and-allowed-origins
Kaleidr。Quota & Rate Limits。Kaleidr 开发者文档。访问日期:2026年8月17日。https://docs.kaleidr.com/platform-api/quota-and-rate-limits
Mapbox。安全使用 Mapbox。Mapbox 文档。访问日期:2026年8月17日。https://docs.mapbox.com/help/dive-deeper/how-to-use-mapbox-securely/
Mapbox。令牌管理。Mapbox 文档。访问日期:2026年8月17日。https://docs.mapbox.com/accounts/guides/tokens/
@misc{ietf_rfc9110_2026,
title = {HTTP Semantics (RFC 9110)},
author = {{IETF}},
note = {Accessed 17 August 2026},
url = {https://www.rfc-editor.org/rfc/rfc9110}
}
@misc{ietf_rfc6750_2026,
title = {The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750)},
author = {{IETF}},
note = {Accessed 17 August 2026},
url = {https://www.rfc-editor.org/rfc/rfc6750}
}
@misc{whatwg_fetch_cors_2026,
title = {Fetch Standard},
author = {{WHATWG}},
note = {CORS protocol; accessed 17 August 2026},
url = {https://fetch.spec.whatwg.org/#http-cors-protocol}
}
@misc{kaleidr_auth_scopes_2026,
title = {Auth and Scopes},
author = {{Kaleidr}},
note = {Kaleidr Developer Docs; accessed 17 August 2026},
url = {https://docs.kaleidr.com/platform-api/auth-and-scopes}
}
@misc{kaleidr_cors_origins_2026,
title = {CORS and Allowed Origins},
author = {{Kaleidr}},
note = {Kaleidr Developer Docs; accessed 17 August 2026},
url = {https://docs.kaleidr.com/platform-api/cors-and-allowed-origins}
}
@misc{kaleidr_quota_2026,
title = {Quota and Rate Limits},
author = {{Kaleidr}},
note = {Kaleidr Developer Docs; accessed 17 August 2026},
url = {https://docs.kaleidr.com/platform-api/quota-and-rate-limits}
}
@misc{mapbox_token_management_2026,
title = {Token Management},
author = {{Mapbox}},
note = {Accessed 17 August 2026},
url = {https://docs.mapbox.com/accounts/guides/tokens/}
}
@misc{mapbox_secure_2026,
title = {How to Use Mapbox Securely},
author = {{Mapbox}},
note = {Accessed 17 August 2026},
url = {https://docs.mapbox.com/help/dive-deeper/how-to-use-mapbox-securely/}
}
@misc{google_maps_security_2026,
title = {Google Maps Platform Security Guidance},
author = {{Google}},
note = {Accessed 17 August 2026},
url = {https://developers.google.com/maps/api-security-best-practices}
}