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 服务器。然后:
- 我的服务器会将浏览器重定向到 google(带有 clientid、secret 等)
- 用户登录,它将被重定向回带有 oauth 代码的服务器
- 服务器使用代码获取令牌,然后是用户配置文件并将令牌和配置文件存储在数据库中,然后使用参数将浏览器重定向到本地主机
- 桌面应用程序捕获参数并将其存储在磁盘上的文件中
下次启动桌面应用程序时,它只会读取参数文件,将生成的数据连同它一起发送到我的服务器
我的问题是:参数应该是什么? google 用户 ID? oauth 令牌?为此桌面应用程序生成的会话 ID?还是别的?
- 当它是google用户id时,它可以方便地用用户id发送数据,其余服务器将按原样存储在db中。但我认为它不安全
- 当它将成为令牌时,其余服务器必须在每个请求中还使用令牌从 google 获取用户配置文件。恕我直言,随每个请求发送令牌也不安全
- 生成会话 ID 意味着将其与用户和令牌一起存储在服务器上,桌面应用程序将只存储它并随每个请求一起发送。但我不知道这样做是否安全
在每个请求中发送 access_token
应该没有问题,因为它们是为此目的而创建的,因此是短暂的。您可以使用 Google Authorization Server endpoint to verify a token 而不是使用它来请求用户配置文件。
如果您仅依赖 Google 进行身份验证,您的工作流程如下所示:
- 客户端(在您的情况下为桌面应用程序)检索
Google id_token
跟随用户登录,然后发送到
服务器
- 服务器验证所述令牌的完整性并提取用户的个人资料数据;这可能意味着在 Google 的端点上进行简单的 GET 以验证此令牌:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
在后续请求中,除了用户的登录过程将自动执行(因为他已获得所有权限和所有权限)之外,实际上什么都不应该改变,因此速度要快得多。 @danielx 说的对,每次发token都没有问题
正如软件开发中的通常情况一样,根据需求,您有几个选择。
强制性要求是您的客户端(桌面)应用程序需要向您的 REST API 发送一些内容,以便 API 最多可以执行两个决定:
- 决定用户是谁。
- 确定用户是否有权执行当前请求的操作。
如果所有经过身份验证的用户都可以访问完全相同的一组操作,那么第二步可能不适用,因此我将介绍这两种情况。
另请注意,对于第一步,发送 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 工作。
TL;DR 在桌面应用程序上使用 google oauth 时,要在磁盘上保存什么以避免重复登录?保存 google 用户 ID?还是令牌?或会话 ID?
我正在创建一个小型桌面应用程序,它必须通过我的 REST API 服务器的身份验证。为此,我正在使用 google oauth2。
想法是,当桌面应用程序将被验证时,它会生成一些数据,这些数据将发送到我的服务器。服务器将使用从 https://www.googleapis.com/userinfo/v2/me
.
在桌面应用程序的第一个 运行 上,它将打开默认浏览器,并为我的服务器 url 并启动本地 http 服务器。然后:
- 我的服务器会将浏览器重定向到 google(带有 clientid、secret 等)
- 用户登录,它将被重定向回带有 oauth 代码的服务器
- 服务器使用代码获取令牌,然后是用户配置文件并将令牌和配置文件存储在数据库中,然后使用参数将浏览器重定向到本地主机
- 桌面应用程序捕获参数并将其存储在磁盘上的文件中
下次启动桌面应用程序时,它只会读取参数文件,将生成的数据连同它一起发送到我的服务器
我的问题是:参数应该是什么? google 用户 ID? oauth 令牌?为此桌面应用程序生成的会话 ID?还是别的?
- 当它是google用户id时,它可以方便地用用户id发送数据,其余服务器将按原样存储在db中。但我认为它不安全
- 当它将成为令牌时,其余服务器必须在每个请求中还使用令牌从 google 获取用户配置文件。恕我直言,随每个请求发送令牌也不安全
- 生成会话 ID 意味着将其与用户和令牌一起存储在服务器上,桌面应用程序将只存储它并随每个请求一起发送。但我不知道这样做是否安全
在每个请求中发送 access_token
应该没有问题,因为它们是为此目的而创建的,因此是短暂的。您可以使用 Google Authorization Server endpoint to verify a token 而不是使用它来请求用户配置文件。
如果您仅依赖 Google 进行身份验证,您的工作流程如下所示:
- 客户端(在您的情况下为桌面应用程序)检索
Googleid_token
跟随用户登录,然后发送到 服务器 - 服务器验证所述令牌的完整性并提取用户的个人资料数据;这可能意味着在 Google 的端点上进行简单的 GET 以验证此令牌:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
在后续请求中,除了用户的登录过程将自动执行(因为他已获得所有权限和所有权限)之外,实际上什么都不应该改变,因此速度要快得多。 @danielx 说的对,每次发token都没有问题
正如软件开发中的通常情况一样,根据需求,您有几个选择。
强制性要求是您的客户端(桌面)应用程序需要向您的 REST API 发送一些内容,以便 API 最多可以执行两个决定:
- 决定用户是谁。
- 确定用户是否有权执行当前请求的操作。
如果所有经过身份验证的用户都可以访问完全相同的一组操作,那么第二步可能不适用,因此我将介绍这两种情况。
另请注意,对于第一步,发送 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 工作。