【问题标题】:Storing external access/refresh tokens存储外部访问/刷新令牌
【发布时间】:2020-09-26 15:58:00
【问题描述】:

我创建了一个 Laravel 应用程序,它请求我的用户使用 oAuth(授权码)访问外部应用程序。很好,我可以将外部应用程序连接到我的用户帐户。但是,外部 API 为我提供了访问和刷新令牌。访问令牌显然过期了,刷新令牌没有。

一旦用户授予我访问权限,我需要将这些令牌存储在某个地方。特别是刷新令牌。访问令牌过期后,我需要刷新访问令牌。我的“问题”是,我不太确定在哪里存储这些令牌。我想到了几个选择:

  • 在数据库中存储加密令牌,链接到用户
  • 将它们存储在缓存中
  • 将它们存储在 Redis 数据库中
  • ...

有很多选择,但我正在寻找最安全的选择。将加密令牌存储在数据库中不是我最喜欢的选择,而是最持久的选择。可以有意或无意地清除缓存。清除缓存后,我需要用户再次授予我对其帐户的访问权限。

存储这些凭据的最佳方式是什么?

【问题讨论】:

  • 您可能根本不需要存储令牌(即在会话中除外)。大多数提供商会记住用户的同意,因此第一个授权流程是非交互式的。

标签: laravel encryption oauth access-token refresh-token


【解决方案1】:

安全

存储这些凭据的最佳方式是什么? 有很多选择,但我正在寻找最安全的选择。

无论您将其存储在何处,始终以加密格式进行。这样即使泄露了也无法重复使用,除非加密密钥也泄露了。

刷新令牌持久性

将加密令牌存储在数据库中不是我最喜欢的选择,而是最持久的选择。

您可以使用会话、JWT 令牌或直接进入数据库来执行此操作。让我们看看选项...

Laravel 会话

如果您在 Laravel 应用程序中使用用户会话,您可以将其加密存储在每个用户的会话中。

Laravel Sessions

由于 HTTP 驱动的应用程序是无状态的,因此会话提供了一种跨多个请求存储用户信息的方法。 Laravel 附带了各种会话后端,这些后端可以通过富有表现力的统一 API 访问。开箱即用地支持流行的后端,例如 Memcached、Redis 和数据库。

Laravel 还支持将会话存储在加密的 cookie 中。

JWT 令牌

如果您使用的是 JWT 令牌,那么您可能正在使用 JWS 令牌,如果是这样,请将其加密存储在 JWS 声明中,或者更好的是,使用 JWE 令牌。

JWT 令牌中的声明是 JWT 令牌有效负载中的键/值对。 JWT Token 由header.payload.signature 组成。有效载荷示例:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

JWS

JSON Web 签名(缩写为 JWS)是 IETF 提出的用于签署任意数据的标准 (RFC 7515)。[1]这被用作各种基于 Web 的技术的基础,包括 JSON Web Token。

JWE

JSON Web 加密 (JWE) 是一种 IETF 标准,它为基于 JSON 和 Base64 的加密数据交换提供标准化语法。[1]它由 RFC7516 定义。与 JSON Web 签名 (JWS) 一起,它是 JWT(JSON Web 令牌)的两种可能格式之一。 JWE 是 JavaScript 对象签名和加密 (JOSE) 协议套件的一部分。

您可以在https://jwt.io/introduction 了解有关 JWT 的更多信息。

数据库

使用对您来说更方便的数据库,也就是您的应用程序中已经可用的数据库。不要仅仅为了存储刷新令牌而引入 Redis,但是如果您已经在使用 Redis,那么它可以是一种替代方案,但我只会将它加密存储在您已经存储用户信息的数据库中。毕竟刷新令牌不是您在每个请求中都执行的操作,因此这里的性能可能不是那么重要。

【讨论】:

  • Nitpick:JWS 不加密数据,因此从技术上讲,refresh_token 在那里并不安全,只是经过验证。
  • 我说过要在 JWS 声明中存储加密的刷新令牌,因此即使攻击者从 JWS 中提取它也是无用的。我还建议改用加密的 JWE 令牌。也许我需要让信息更清楚?
  • 我不知道您所说的索赔是什么意思。原始 RFC 没有使用该术语。
  • RFC 7519 在其摘要中陈述了声明,但您可能想改为阅读 this introduction。基本上,一个声明是 JWT 令牌有效负载中的每个键/值对,有效负载是 JWT 令牌三个组件的中间部分,即header.payload.signature
  • 好的,所以当只使用没有 JWE 的 JWS 时,声明不会加密。
【解决方案2】:

内存和加密数据库是您的最佳选择。内存是不够的,因为在任何类型的内存刷新的情况下你都会丢失它。所以你只剩下加密的数据库了

【讨论】:

    猜你喜欢
    • 2021-07-16
    • 2021-09-13
    • 2021-07-08
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2017-01-20
    • 1970-01-01
    相关资源
    最近更新 更多