我们什么时候应该删除 SSO 访问令牌?

When should we drop the SSO access token?

TL;DR - 当用户在另一个选项卡中注销时,我们如何使访问令牌过期?

详情:

SSO documentation 中说:

When to call the method

If your add-in cannot be used when no user is logged into Office, then you should call getAccessToken when the add-in launches and pass allowSignInPrompt: true in the options parameter of getAccessToken.

很好,很清楚。但是我们什么时候应该停止使用令牌呢?有没有我们可以用来知道用户退出的事件? (我还没找到。)

我问是因为即使用户在另一个选项卡中注销,令牌仍会继续工作。因此,如果我们将令牌保留任何时间长度,就会留下用户帐户被错误使用的场景。例如:

  1. 用户登录
  2. 用户打开加载项;加载项获取访问令牌并保留它
  3. 用户打开另一个选项卡
  4. 用户在另一个选项卡中退出他们的帐户
  5. 用户离开
  6. 其他人使用加载项做了他们不应该做的事情

我刚刚这样做了(好吧,不是第 6 步),并且访问令牌继续在带有加载项的选项卡中工作。是的,用户可能应该在注销时关闭选项卡。是的,他们也不应该让他们的电脑处于解锁状态。但我想在那种情况下使令牌过期。

这是另一个更容易看到的情况:

  1. 用户登录
  2. 用户打开加载项
  3. 用户意识到他们需要切换帐户。由于您不能在 Web Excel 中执行此操作,因此他们会在另一个选项卡中执行此操作
  4. 用户尝试使用加载项 — 它使用的是旧帐户,而不是切换到的帐户

我们 曾经 只是在每次需要时获取令牌,但我们最近 运行 开始遇到速率限制问题。所以现在我们将它短暂地缓存起来,但是弄清楚短暂的时间是多么棘手,特别是在上面的场景 #2 中。我们想避免速率限制,但不要让 window 打开的时间过长。知道用户何时注销(不达到速率限制)可以让我们做到这一点。

由于在我发布问题时我们遇到了感知速率限制,我们决定将其缓存一分钟,并确保我们的代码中不会重叠调用 getAccessToken。这在过去几年中运作良好。但是前几天我注意到文档(现在)says:

Don't cache the access token

Never cache or store the access token in your client-side code. Always call getAccessToken when you need an access token. Office will cache the access token (or request a new one if it expired.) This will help to avoid accidentally leaking the token from your add-in.

所以要么我在 2020 年错过了它,要么它已经更新了(显然我倾向于认为后者,但是嘿,我们都错过了)。

有可能我们认为是速率限制实际上是平台不允许重叠调用或未正确处理它们。我们通过确保对 getAccessToken 的调用按照这些行使用包装函数进行序列化来解决这个问题。

let lastPromise = Promise.resolve("");
function getToken() {
    return lastPromise = lastPromise
        .catch(() => {}) // We don't care if the _last_ one failed, just that it settled
        .then(() => OfficeRuntime.auth.getAccessToken());
}