单页面应用程序
通过 IBM Cloud® App ID,您可以快速向单页面应用程序 (SPA) 添加授权和认证。 SPA 完全在浏览器中运行,没有由您管理的后端,也无需在使用应用程序期间重新装入页面。 与 SPA 一起使用的一些常见框架为 Angular 和 React。
您的应用程序是否有由您控制的后端? 如果有,那么 SPA 流程不适合您。 请尝试使用 Web 应用程序流程!
了解流程
虽然它是当前 SPA 的行业标准,但由于一些安全问题,OAuth 工作组不再推荐使用隐式流程。 根据他们的建议,App ID 被配置为使用 PKCE 的授权码流。
- 用户尝试登录到单页面应用程序。
- App ID SDK 为授权请求创建代码验证器,这是代码质询的明文版本。 客户端在发送授权请求时,会一起发送代码质询以及用于对质询进行编码的质询方法。
- App ID 将在新窗口中启动认证流程。
- 用户选择身份提供者以进行认证并完成登录过程。
- 应用程序上的 App ID SDK 收到授权代码。
- 然后,SDK 向 App ID 令牌端点发出 XHR 请求并随同发送授权代码和代码验证器,以获取访问令牌和身份令牌。
您是否在将 SSO 用于 Cloud Directory? 您可以使用 App ID 客户端 SDK 自动获取一对新的令牌,而无需用户明确登录。 有关更多信息,请参阅静默登录。
为什么要使用授权代码 + PKCE?
单页面应用程序受自身性质所限,无法安全地存储私钥。 “授权 + PKCE”流程是 OAuth 2.0 授权代码流程的一种变体,使用一次性代码验证器和质询取代私钥,解决了此问题。 验证器和提问确保调用授权和令牌端点的实体相同。 此过程意味着攻击者将无法在不知道代码验证器的情况下从授权服务器请求令牌。
虽然隐式流程是当前的行业标准,但仍存在一些安全漏洞。 例如,隐式流程使用重定向 URI 来获取令牌,而“授权 + PKCE”流程使用 XHR 请求规避了这种做法。 由于存在安全缺陷,因此不再建议使用隐式流程,或不再将其视为安全流程,具体原因如下:
-
隐式流程将标记作为 URL 的一部分返回--作为查询参数或在哈希片段中。 这种一来,就可以拦截并访问令牌。 令牌可能会保存在用户的浏览器历史记录或日志中。 历史记录或日志可能存储在云服务中并发送到多个设备,这也增加了风险。
-
隐式流量容易受到 重定向 URI 攻击,这意味着攻击者可能会用自己选择的目的地替换已批准的重定向 URI。 如果存在重定向 URI 攻击,那么用户将访问已更改的链接来授权其客户端。 授权后,用户会被重定向到攻击者 URI,这将授予攻击者访问权来访问用户的合法令牌。
相关的重要问题很多,上面仅举几例予以说明。 如需了解更多信息,请参阅 OAuth 2.0 当前最佳安全实践。
开始之前
开始之前,请确保已满足以下先决条件。
- App ID 服务的实例。
- 在 App ID 服务仪表板中设置的 重定向 URI。
- 单页面应用程序。 如果没有单页面应用程序,但希望试用该流程,请尝试从 App ID 仪表板的“概述”页面中下载样本应用程序。
使用 GUI 创建应用程序凭证
凭证用于将应用程序连接到 App ID。 要创建凭证,请向 App ID 注册应用程序。
SPA 凭据中不会返回客户机密文。 不需要授权 + PKCE 流程中的私钥。 您无法在 SPA 流程中使用常规的 Web 应用程序凭证。
- 在要在其中工作的区域中登录到 IBM Cloud 仪表板。
- 导航至应用程序选项卡,然后单击添加应用程序。
- 为应用程序提供名称。
- 从类型下拉列表中,选择单页面应用程序。
- 单击保存。
- 在表中,单击查看凭证以查看以下配置中所需的信息。
使用 API 创建应用程序凭证
凭证用于将应用程序连接到 App ID。 要创建凭证,请向 App ID 注册应用程序。
SPA 凭据中不会返回客户机密文。 不需要授权 + PKCE 流程中的私钥。 您无法在 SPA 流程中使用常规的 Web 应用程序凭证。
-
向 /management/v4/
/应用程序 端点。curl -X POST \ https://us-south.appid.cloud.ibm.com/management/v4/<tenantID>/applications/ \ -H 'accept: application/json' \ -H 'Authorization: Bearer <IAMToken>' \ -H 'Content-Type: application/json' \ -d '{"name": "MySampleSPA", "type": "singlepageapp"}'
示例响应:
{ "clientId": "<clientID>", "tenantId": "<tenantID>", "name": "MySampleSPA", "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/<tenantID>", "type": "singlepageapp" }
配置 JavaScript SDK
要在应用程序中安装 SDK,请使用以下步骤作为指南。
-
使用命令提示符切换到包含应用程序的目录。
-
使用 NPM 或通过在主 HTML 文件中链接 CDN 来安装 App ID 服务。
-
要使用 NPM,请运行以下命令。
npm install ibmcloud-appid-js
-
要添加 CDN,请将以下链接添加到主 HTML 文件。
<script src="https://cdn.appid.cloud.ibm.com/appid-0.3.0.min.js"></script>
-
-
向应用程序添加客户端标识和发现端点以初始化 SDK。
const appID = new AppID(); await appID.init({ clientId: '<spaClientID>', discoveryEndpoint: '<wellKnownEndpoint>' });
-
在应用程序代码中,配置“登录”按钮后,添加对
signin
的调用。 此调用将打开一个弹出窗口,其中提示用户输入其凭证。 成功认证后,该屏幕会关闭,此时用户已经过认证。const tokens = await appID.signin();
配置静默登录
启用了用于 Cloud Directory 的 SSO 后,如果使用静默登录,那么可以自动获取用户的新令牌,而无需用户重新认证。 要启用静默登录,请使用以下步骤作为指南。
SPA 流程中不会返回刷新令牌。
-
在 App ID 仪表板中,导航至 Cloud Directory > 单点登录。
-
将启用单点登录切换为已启用。
-
单击保存。
-
将以下代码添加到应用程序中。 请确保将应用程序配置为在静默登录失败时显示“登录”按钮。
const tokens = await appID.silentSignin(); if (!tokens) { document.getElementById('login').addEventListener('click', async () => { const tokens = await appID.signin(); }); }