我应该将 id 令牌从我的 SPA 发送到我的 rest 后端吗?

Posted

技术标签:

【中文标题】我应该将 id 令牌从我的 SPA 发送到我的 rest 后端吗?【英文标题】:Should I send the id token from my SPA to my rest backend? 【发布时间】:2018-06-17 14:34:40 【问题描述】:

我有一个由 rest api 服务器支持的 SPA 应用程序。

我使用 Auth0 通过隐式授权流程进行身份验证和授权。 我阅读的所有示例都说明我应该将收到的访问令牌发送到 api 以进行授权。例如:https://auth0.com/blog/why-should-use-accesstokens-to-secure-an-api

另一方面,我读到访问令牌不能用作身份验证的证明:http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html https://oauth.net/articles/authentication/

这意味着,我不能信任我的访问令牌上的 sub 声明,以确保这确实是用户而不是另一个发送其访问令牌的客户端。 这意味着,如果我将 facebook 用作 IDP,另一个 Web 应用程序可以将颁发给用户使用的访问令牌发送到我的服务器,并且因为访问令牌没有 aud 声明,我的服务器会认为用户已通过身份验证在我的网络应用程序中。 此外,我看到 google 登录确实引导 spa 向服务器发送 id 令牌:https://developers.google.com/identity/sign-in/web/backend-auth

所以:我应该将 id 令牌(用于身份验证)和访问令牌(用于授权)都发送到我的服务器吗?

【问题讨论】:

【参考方案1】:

正如你所指出的,我通过了 Authenticate with a backend server。正如它所建议的,可以使用 id 令牌对后端服务器进行身份验证。这不仅被谷歌推荐,其他一些实体也推荐。但 id 令牌旨在供依赖方(客户端)验证和认证最终用户。访问令牌是应该用于访问资源的令牌。

您可以考虑的另一种选择是使用 OpenID Connect 规范定义的用户信息端点

User info endpoint

UserInfo 端点是一个 OAuth 2.0 受保护资源,它返回有关经过身份验证的最终用户的声明。为了获得有关最终用户的请求声明,客户端使用通过 OpenID Connect 身份验证获得的访问令牌向 UserInfo 端点发出请求。这些声明通常由一个 JSON 对象表示,该对象包含声明的名称和值对集合。

Google 确实提供了用户信息端点。他们的documentation's获取用户配置文件信息部分解释了端点、如何调用它和响应详细信息。

要获取有关用户的其他个人资料信息,您可以使用访问令牌(您的应用程序在身份验证流程中收到)和 OpenID Connect 标准:

成功的详细信息将显示最终用户信息,其格式以 People: getOpenIdConnect 格式解释。

这样可以避免将 id 令牌暴露给其他方。并且您的后端可以使用访问令牌来访问这些信息以检测最终用户并据此进行身份验证。

无论这些替代方法如何,id 令牌都旨在用于身份验证。因此,只要您保护 id 令牌,就可以将其传递给服务器并使用声明来识别最终用户并验证令牌有效性。

【讨论】:

我还是有问题。假设我有一个服务于 2 个客户端的后端。如果在服务器中我想确保用户(在 sub 声明中描述)使用第一个客户端进行了身份验证,我无法确保因为访问令牌的“aud”声明包含服务器 url。因此,第二个恶意客户端可以使用其用户生成的访问令牌并在第一个客户端中进行虚假身份验证,如文章中所述。因此,确保它的唯一方法是发送 id 令牌并检查“aud”声明。合理吗? 好吧,在这种情况下,恶意客户端必须对最终用户进行身份验证才能获得访问令牌(遵循有效的 OpenID Connect 流程并获得适当的最终用户授权)。并且即使获取令牌,当您的服务器获取访问令牌并检索用户信息时,您必须在验证之前验证服务器的用户注册表并验证用户信息。但是,是的,如果您的用户在不同的服务之间共享,则可能存在潜在问题(无论客户端是否恶意)。 归根结底,id token 用于身份验证。因此,只要您保护它(SSL 和客户端存储安全),就可以与服务器共享它以进行身份​​验证。但是我也展示了其他方法。

以上是关于我应该将 id 令牌从我的 SPA 发送到我的 rest 后端吗?的主要内容,如果未能解决你的问题,请参考以下文章

SPA 的 Cookie 与基于令牌的身份验证?

我如何通过 json 将数据从我的设备发送到我的 php 文件

没有设备令牌的 ios 推送通知/消息

如何将 FCM 令牌发送到我的 php 服务器

如何将数据从我的数据库 (Firebase Firestore) 发送到我的 React Native 应用程序?

如何将数据从我的 main.js 发送到我的 index.html(电子)