如何在js webapp中为仅承载后端客户端获取令牌

时间:2018-11-18 17:16:56

标签: oauth-2.0 keycloak bearer-token

我为我的应用设置了此设置

  1. Keycloak服务器
  2. 受Keycloak保护的nodejs后端(仅承载者)
  3. PHP / Reactjs前端

前端可以选择受登录保护。对于某些用户,将需要登录,这会将用户重定向到Keycloak服务器。用户登录后,前端将具有一个承载令牌,以对受密钥库保护的后端进行api调用。

我的问题是如何为不需要登录的用户(匿名用户)获取承载令牌。

我尝试过这种方法:

  1. 创建了供PHP使用的“机密”客户端。
  2. 前端PHP使用client_id和client_secret获取承载令牌并将它们传递给javascript(这是指在标记中打印出标记值,该标记是全局变量)
  3. 最初,由于php传递的access_token是新鲜的/有效的,因此前端可以成功进行api调用。
  4. access_token过期后,我需要使用refresh_token来获取一个新的。
  5. 但是,为此,我需要在js应用程序中不可用的client_secret(如您所知,不建议在js应用程序中保存client_secret和密码)。

我被困在这里。我进行了研究,阅读了很多文档,但没有找到实现该目标的方法。

另一个让我着迷的想法是使载体access_token长寿(例如1个小时)。但是,某些用户可能会使用该应用程序一个多小时。

目前,我不确定是否可以从JavaScript网络应用程序匿名调用受keycloak保护的后端。

具有很长寿命(例如6个小时)的access_tokens是错误的吗?我还有什么其他选择?

2 个答案:

答案 0 :(得分:1)

在不增加太多复杂性的情况下,当访问令牌过期(用户未授权的请求)时,重定向用户以重新登录。这要容易得多,因为在许多情况下,流程都是相同的。

另一种选择是使用类似会话的方法来处理此问题,这确实增加了复杂性。 https://openid.net/specs/openid-connect-session-1_0.html

答案 1 :(得分:1)

我也遇到过类似的情况。您可以使用以下方法。

  • 您的API始终受到访问令牌的保护
  • 最初,您的PHP后端使用 Client Credentials Grant
  • 来获取访问令牌。
  • 一旦加载UI,您将对PHP后端进行JS调用并获取相关的访问令牌。您将其存储到本地存储
  • 此呼叫受会话保护。最初是未经身份验证/匿名访问
  • 如果您需要访问具有不同范围的令牌(范围仅授予登录用户的范围,非匿名情况),那么您将使最终用户遵循登录过程以获取新令牌
  • 一旦收到令牌,您将再次将它们存储在与后端和前端进行的会话中
  • UI可以通过相同的后端调用获取到前端的访问令牌

通过这种方式,您无需对访问UI代码的令牌值进行硬编码。另外,后端调用受会话保护。

另外,

  • 刷新令牌存储在后端。因此可以安全地存储和刷新
  • 客户端凭据永远不会暴露在前端

只有负担是后端的会话维护。但是,围绕此构建了许多最佳实践。