停止刷新令牌的竞争条件?

cho*_*bo2 5 javascript c# authentication jwt reactjs

我有一个 ReactJS 网站和 asp.net core 后端,但我遇到刷新令牌问题。

当有人登录我的网站时,他们会获得访问令牌和刷新令牌(非常标准)。现在我设置了一个比访问令牌的时间短的计时器。

当他们打开多个选项卡时,这一切都非常有效。问题是他们都共享本地存储(需要自动登录,所以不能使用会话存储)

设想

2 个选项卡相继打开。在访问令牌失效前 2 分钟设置 2 个计时器。

第一次触发时,首先将刷新令牌发送到服务器并带回新的刷新/访问令牌。在服务器上,发送的刷新令牌将被删除。

第二个计时器在第一个计时器之后不久触发(当第一个计时器正在工作时),但现在很可能刷新令牌已被删除,从而使该请求无效。

我如何停止这种竞争条件?

var foundRefreshToken = dbContext.Tokens.FirstOrDefault(x => x.Value == refreshToken);

if (foundRefreshToken == null)
{
    return null;
}

var newRefreshToken = CreateRefreshToken(foundRefreshToken.ClientId, foundEmployee.Id);

dbContext.Tokens.Remove(foundRefreshToken);
dbContext.Tokens.Add(newRefreshToken);
dbContext.SaveChanges();


private Token CreateRefreshToken(string clientId, string userId)
    {
        return new Token()
        {
            ClientId = clientId,
            EmployeeId = userId,
            Value = GenerateRefreshToken(),
            CreatedDate = DateTime.UtcNow
        };
    }

// high level js
  refreshTimer;
  setRefreshTimer(intervals) {
    this.clearRefreshTimer();
    this.refreshTimer = setInterval(() => {
      this.refreshAuthentication();
    }, intervals);
  }
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一两件事是不要删除刷新令牌(但这会导致自动登录出现问题)

或者我在本地存储中有一个标志,用于“锁定”第一个选项卡以进行刷新,而其他选项卡则等待查看它是否执行刷新(猜测需要另一个计时器)。如果没有,那么下一个会尝试。

还有其他人有其他想法吗?

Car*_*rge 1

创建令牌和刷新令牌时都应该有一个到期日期,例如:

return new Token()
        {
            ClientId = clientId,
            EmployeeId = userId,
            Value = GenerateRefreshToken(),
            CreatedDate = DateTime.UtcNow,
            ExpirationDate = <you decide>
        };
Run Code Online (Sandbox Code Playgroud)

对于每个请求,您都应该通过比较日期来检查您的令牌是否已过期。如果它已过期,您可以使用保持用户身份验证。最终,您甚至可以永远不会使刷新令牌过期,因为它必须由您的应用程序安全地存储。

刷新令牌和短期令牌背后的想法是,如果令牌被泄露,黑客只有 10 分钟的时间才需要刷新令牌来生成新令牌......