OAuth - 在磁盘上存储什么

OAuth - what to store on disk

TL;DR 在桌面应用程序上使用 google oauth 时,要在磁盘上保存什么以避免重复登录?保存 google 用户 ID?还是令牌?或会话 ID?

我正在创建一个小型桌面应用程序,它必须通过我的 REST API 服务器的身份验证。为此,我正在使用 google oauth2。

想法是,当桌面应用程序将被验证时,它会生成一些数据,这些数据将发送到我的服务器。服务器将使用从 https://www.googleapis.com/userinfo/v2/me.

收到的 google 用户 ID 存储数据

在桌面应用程序的第一个 运行 上,它将打开默认浏览器,并为我的服务器 url 并启动本地 http 服务器。然后:

  1. 我的服务器会将浏览器重定向到 google(带有 clientid、secret 等)
  2. 用户登录,它将被重定向回带有 oauth 代码的服务器
  3. 服务器使用代码获取令牌,然后是用户配置文件并将令牌和配置文件存储在数据库中,然后使用参数将浏览器重定向到本地主机
  4. 桌面应用程序捕获参数并将其存储在磁盘上的文件中

下次启动桌面应用程序时,它只会读取参数文件,将生成的数据连同它一起发送到我的服务器

我的问题是:参数应该是什么? google 用户 ID? oauth 令牌?为此桌面应用程序生成的会话 ID?还是别的?

在每个请求中发送 access_token 应该没有问题,因为它们是为此目的而创建的,因此是短暂的。您可以使用 Google Authorization Server endpoint to verify a token 而不是使用它来请求用户配置文件。

如果您仅依赖 Google 进行身份验证,您的工作流程如下所示:

  1. 客户端(在您的情况下为桌面应用程序)检索
    Google id_token 跟随用户登录,然后发送到 服务器
  2. 服务器验证所述令牌的完整性并提取用户的个人资料数据;这可能意味着在 Google 的端点上进行简单的 GET 以验证此令牌:https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}

在后续请求中,除了用户的登录过程将自动执行(因为他已获得所有权限和所有权限)之外,实际上什么都不应该改变,因此速度要快得多。 @danielx 说的对,每次发token都没有问题

正如软件开发中的通常情况一样,根据需求,您有几个选择。

强制性要求是您的客户端(桌面)应用程序需要向您的 REST API 发送一些内容,以便 API 最多可以执行两个决定:

  1. 决定用户是谁。
  2. 确定用户是否有权执行当前请求的操作。

如果所有经过身份验证的用户都可以访问完全相同的一组操作,那么第二步可能不适用,因此我将介绍这两种情况。

另请注意,对于第一步,发送 Google 用户 ID 不是一个有效的选项,因为该信息可以被其他方获取,并且不会确保用户确实进行了身份验证以使用您的应用程序。

选项 1 - 身份验证无精细授权

始终发送 id_token 或使用您的自定义会话标识符交换该令牌都满足先前的要求,因为 id_token 包含明确指示用户已通过身份验证可以使用您的应用程序的受众,并且会话标识符是由您的应用程序生成的,因此它也可以确保这一点。对您的 API 的请求需要使用 HTTPS,否则令牌或会话 ID 很容易被攻击者捕获。

如果您选择 id_token 替代方案,您需要考虑令牌将过期;为此,再次提供几个选项:

  • 再次重复验证过程;如果用户仍然有一个会话,它确实会更快,但你仍然必须打开浏览器、本地服务器并重复整个步骤。
  • 在进行第一次身份验证时请求offline_access

最后一个选项你应该得到 refresh token that would allow for your application to have a way to identify the user even after the first id_token expires. I say should, because Google seems to do things a bit different than the specification, for example, the way to obtain the refresh token is by providing access_type=offline instead of the offline_access from OpenID Connect.

就个人而言,我会选择会话标识符,因为您可以更好地控制生命周期,而且它也可能更简单。

选项 2 - 身份验证 + 细粒度授权

如果您的 REST API 需要一个细粒度的授权系统,那么最好的方法是使用 Google 对您的用户进行身份验证,然后拥有一个符合 OAuth 2.0 的授权服务器为您的 API.

发行特定的访问令牌

对于授权服务器实现,您可以:

  • 自己实施或利用开源组件
    可能耗时、复杂,安全风险的缓解全靠你了

  • 使用第三方 OAuth 2.0 作为服务授权提供程序,例如 Auth0
    容易上手,取决于使用量(Auth0上的免费计划goes up to 7000 users)它会花钱而不是时间

披露:我在 Auth0 工作。