使用第三方 OAuth2 服务为 SPA/REST 应用存储 refresh_token 的位置?
Where to store refresh_token for SPA/REST app with third-party OAuth2 service?
我有一个客户端 (SPA)/服务器 (REST) 应用程序,我需要对客户端进行身份验证并使它们在资源服务器中保持登录状态。
应用程序通常必须使用位于第三方授权服务器上的外部 OAuth2 服务。
现在的问题是:refresh_token 应该存储在哪里?我有两个想法。
我故意省略了 refresh_token 过期的情况。
假设
- 始终返回有效令牌以响应对任何安全资源的请求和登录请求。
- 与授权服务器的所有通信都必须通过资源服务器,因为需要 client_id 和 client_secret。
第一个场景
- 服务器存储由令牌映射的refresh_token,并将令牌发送给客户端以响应登录请求。
- 客户端使用令牌发出请求。
- 服务器检查令牌是否有效。如果不是,它使用与令牌关联的 refresh_token 生成一个新令牌。现在一分钟(或任何配置的持续时间)旧令牌映射到新令牌,新令牌映射到 refresh_token 以处理使用旧令牌排队的请求。
- 客户端使用令牌发出请求。
- 服务器检查令牌是否有效。如果不是,它会检查令牌是否映射到新令牌。如果是这样,它的行为就像使用新令牌发送请求一样(请参阅第 3 步)。否则发送 401。
第二种情况
- 服务器 将令牌和 refresh_token 发送到客户端以响应登录请求。
- 客户端使用令牌发出请求。
- 服务器检查令牌是否有效。如果不是,它会返回 401。
- 如果客户端使用 401 状态的响应,它会尝试刷新令牌并使用新令牌发出相同的请求。
我知道这两种解决方案都有其弱点。有什么好的做法适用于这个问题吗?
第二种情况在我看来是最可行的。首先,您的授权服务器不必与您的资源服务器相同。您仅使用刷新令牌从授权服务器获取新的访问令牌。但是授权服务器和资源服务器可以在同一台服务器上实现。
第一种情况下的客户端如何取回新的访问令牌?它正在请求资源(第 3 步)并且不希望取回新令牌。
我会在客户端将刷新令牌存储在浏览器本地存储或其他地方。这不是高度安全,但可能是你能做的最好的。
access-token 和 refresh-token 应该留在它们被获取的地方,特别是如果你的后端没有使用 HTTPS。
没有自己的 REST 后端的 SPA 应该使用 OAuth 隐式流来获取访问令牌。隐式流不支持刷新令牌。
具有服务器端后端的应用程序应使用授权代码流(您的情况)。授权代码由后端交换以访问和刷新令牌,并且应该保留在那里。您的 REST 后端可以使用 access-token 访问第三方资源,并在必要时使用 refresh-token 更新 access-token。
我有一个客户端 (SPA)/服务器 (REST) 应用程序,我需要对客户端进行身份验证并使它们在资源服务器中保持登录状态。 应用程序通常必须使用位于第三方授权服务器上的外部 OAuth2 服务。 现在的问题是:refresh_token 应该存储在哪里?我有两个想法。
我故意省略了 refresh_token 过期的情况。
假设
- 始终返回有效令牌以响应对任何安全资源的请求和登录请求。
- 与授权服务器的所有通信都必须通过资源服务器,因为需要 client_id 和 client_secret。
第一个场景
- 服务器存储由令牌映射的refresh_token,并将令牌发送给客户端以响应登录请求。
- 客户端使用令牌发出请求。
- 服务器检查令牌是否有效。如果不是,它使用与令牌关联的 refresh_token 生成一个新令牌。现在一分钟(或任何配置的持续时间)旧令牌映射到新令牌,新令牌映射到 refresh_token 以处理使用旧令牌排队的请求。
- 客户端使用令牌发出请求。
- 服务器检查令牌是否有效。如果不是,它会检查令牌是否映射到新令牌。如果是这样,它的行为就像使用新令牌发送请求一样(请参阅第 3 步)。否则发送 401。
第二种情况
- 服务器 将令牌和 refresh_token 发送到客户端以响应登录请求。
- 客户端使用令牌发出请求。
- 服务器检查令牌是否有效。如果不是,它会返回 401。
- 如果客户端使用 401 状态的响应,它会尝试刷新令牌并使用新令牌发出相同的请求。
我知道这两种解决方案都有其弱点。有什么好的做法适用于这个问题吗?
第二种情况在我看来是最可行的。首先,您的授权服务器不必与您的资源服务器相同。您仅使用刷新令牌从授权服务器获取新的访问令牌。但是授权服务器和资源服务器可以在同一台服务器上实现。
第一种情况下的客户端如何取回新的访问令牌?它正在请求资源(第 3 步)并且不希望取回新令牌。
我会在客户端将刷新令牌存储在浏览器本地存储或其他地方。这不是高度安全,但可能是你能做的最好的。
access-token 和 refresh-token 应该留在它们被获取的地方,特别是如果你的后端没有使用 HTTPS。
没有自己的 REST 后端的 SPA 应该使用 OAuth 隐式流来获取访问令牌。隐式流不支持刷新令牌。
具有服务器端后端的应用程序应使用授权代码流(您的情况)。授权代码由后端交换以访问和刷新令牌,并且应该保留在那里。您的 REST 后端可以使用 access-token 访问第三方资源,并在必要时使用 refresh-token 更新 access-token。