oauth-2.0 - 如何在 js webapp 中为仅承载后端客户端获取令牌
问题描述
我为我的应用程序设置了这个:
- 密钥斗篷服务器
- 受 Keycloak 保护的 nodejs 后端(仅承载)
- PHP/Reactjs 前端
前端是可选的登录保护。对于某些用户,需要登录,这会将用户重定向到 Keycloak 服务器。用户登录后,前端将拥有一个不记名令牌,用于对受 keycloak 保护的后端进行 api 调用。
我的问题是如何为不需要登录的用户(匿名用户)获取不记名令牌。
我尝试了这种方法:
- 创建了供 PHP 使用的“机密”客户端。
- 前端 PHP 使用 client_id 和 client_secret 获取不记名令牌并将它们传递给 javascript(我的意思是,在标签内打印出令牌值,这是一个全局变量)
- 最初,前端会成功调用 api,因为 php 传递的 access_token 是新鲜/有效的。
- 在 access_token 过期后,我需要使用 refresh_token 获取一个新的。
- 但是,为此我需要在 js 应用程序中不可用的 client_secret(如您所知,不建议在 js 应用程序中保存 client_secret 和密码)。
我被困在这里。我进行了研究,阅读了很多文档,但未能找到实现这一目标的方法。
我想到的另一个想法是让不记名 access_token 长寿命(例如 1 小时)。但是,有些用户可能会使用该应用程序超过一个小时。
在这一点上,我不确定是否可以从 javascript Web 应用程序匿名调用受 keycloak 保护的后端。
拥有很长的寿命(例如,6 小时)access_tokens 是错误的吗?我还有什么其他选择?
解决方案
我遇到过类似的情况。您可以使用以下方法。
- 您的 API 始终受到访问令牌的保护
- 最初,您的 PHP 后端使用Client Credentials Grant检索访问令牌
- 加载 UI 后,您对 PHP 后端进行 JS 调用并获取相关的访问令牌。您将其存储到本地存储
- 此调用受会话保护。最初是未经身份验证/匿名访问
- 如果您需要具有不同范围的访问令牌(范围仅授予登录用户,非匿名情况),那么您让您的最终用户遵循登录过程以获取新令牌
- 收到令牌后,您再次将它们存储在与后端和前端的会话中
- UI 可以通过同一个后端调用获取到前端的访问令牌
这样,您就不会将访问令牌值硬编码到您的 UI 代码中。此外,后端调用受会话保护。
此外,
- 刷新令牌存储在后端。所以存储和刷新是安全的
- 客户端凭据永远不会暴露给前端
唯一的负担是与后端的会话维护。但是围绕此建立了许多最佳实践。!
推荐阅读
- python - 适用于 Linux 2 的 Windows 子系统:Ubuntu,连接到外部 PostgreSQL 数据库
- bash - 如何打印包含第 n 列字符串完全匹配的 CSV 文件中的所有行?
- javascript - 当我单击编辑按钮时,所有按钮都被相同的用户名单击
- javascript - 在循环中向对象添加多个属性
- php - Stripe Payments 将我自己的数据库表链接到 Stripe 上的客户 ID
- javascript - m.route.param 返回“未定义”
- java - 在 Vaadin Flow 中的布局中居中小部件
- c - 传递 'strcmp' 的参数 1 使指针从整数而不进行强制转换
- javascript - 如何将 div 元素的切换设置为首先隐藏并且仅在单击后显示?
- swift - 当我转到另一个视图时,为什么不调用 deinit ?