【问题标题】:Xero oauth2 token refresh in distributed ruby environmentXero oauth2 分布式 ruby​​ 环境中的令牌刷新
【发布时间】:2020-07-21 00:16:44
【问题描述】:

我们有一个 ruby​​ rails 前端和分布式后端服务,通过 Redis 运行批处理作业。

前端将获取初始的 Xero oauth2 令牌。

令牌将在 30 分钟后过期,刷新令牌持续 60 天(很棒),但只能使用一次。

当多个后端进程尝试访问 Xero 并且令牌已过期时,只有一个可以成功所有其他进程都会失败,因为刷新令牌是一次性使用的。

数据库事务边界使得通过数据库共享令牌变得不切实际。

我考虑过以下解决方案(我不喜欢其中任何一个):

  • 处理所有 xero 交互的单例。
  • 在重试过程中包装 xero 并检查 Redis 中可能包含的令牌 已被另一个进程更新。
  • 让用户反复通过oauth2登录获取token 每个后端进程。

不幸的是,我对 Ruby 和 Redis 都是新手,所以在这个环境中的实现细节会非常有用。

【问题讨论】:

    标签: ruby-on-rails ruby redis oauth-2.0 xero-api


    【解决方案1】:

    所以这就是我采取的方法。

    从数据库中获取令牌或刷新令牌时:在新线程上执行此操作,以确保活动记录使用单独的数据库连接。这可确保数据库事务不会干扰查看最新版本的令牌。

    【讨论】:

      【解决方案2】:

      我强烈建议您不要将具有实际令牌凭据的作业作为传递给 Redis 的元数据排入队列。

      您的 access_token 和 refresh_token 应该存储在一个地方。当您将作业排入队列时,您应该只传递一个 user_id,在这种情况下,当它被处理时,它会查找 user.token_set,然后将该 user.token_set['access_token'] 传递给 xero_client(或者无论如何你使用 xero-ruby SDK 进行设置。

      当您重新刷新 access_token 时,会返回一个新的 token_set,包括一个新的 refresh_token。冲洗并重复。

      数据库事务边界使得通过数据库共享令牌变得不切实际

      这让我有点困惑。后台作业在做什么?他们是否没有处理数据并将其读/写到您将存储该 token_set 的同一数据库中?他们是否严格调用非应用级别的 db/api?

      【讨论】:

      • 如果令牌存储在数据库中并且多个事务作业同时运行,那么如果令牌过期,则两者都需要刷新(只有一个可以成功)并且由于数据库事务,两者都不能查看其他对存储在数据库中的令牌的更新。这将导致一个事务失败并且必须回滚。
      • “ 每次执行令牌刷新时,都应保存响应中返回的新刷新令牌。如果出于某种原因,您的应用没有收到响应,您可以在 30 分钟的宽限期内重试现有令牌”> developer.xero.com/documentation/oauth2/auth-flow 这应该有助于解决任何疯狂的倒霉时机。此外,每个后台作业都应该每次都刷新并保存令牌集。你在用sidekiq吗?如果遇到任何故障,重试任何作业并刷新令牌也应该相当简单。
      • 当批次运行超过 30 分钟时,它肯定会发生。但即使是一分钟的批次也有 1/30 的机会。鉴于批次运行时间很长(数小时),回滚是不可取的、昂贵的,而且如果不确定的话,很有可能。这里的关键问题是长时间运行的事务(使数据库的更新不可见)将导致一个或多个进程看不到更新的令牌,并且在不回滚长达数小时的事务的情况下无法获取它。
      猜你喜欢
      • 2022-11-11
      • 2017-04-20
      • 1970-01-01
      • 2021-03-02
      • 2017-12-13
      • 2012-07-21
      • 2017-05-29
      • 2017-03-29
      • 2016-08-13
      相关资源
      最近更新 更多