微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用OAuth和/或OpenID开发RESTful API

如何解决使用OAuth和/或OpenID开发RESTful API

我正在努力地通过多个外部令牌提供程序来实现OAuth或OpenID。由于从我的角度来看,像google这样的提供程序将这两个规范混合在一个api中,因此我在保护资源和处理用户数据的方式上将这两种机制区别开来。 OpenID仅用于身份验证,我会产生自己的access_tokens并自己保留所有用户数据,而OAuth另一方面会提供外部access_tokens并管理用户数据。

涉及的实体:

  1. 外部提供商-这是我对OAuth / OpenID提供商(如Google OAuth)的称呼
  2. 后端-主要用作客户端的RESTful API的服务器
  3. 客户端-需要访问后端提供的资源的应用(例如SPA,IOS应用,桌面客户端)

我正在为几种不同类型的客户端(包括Web,iOS / Android)开发一个快速后端(REST API)。据我了解,我有以下选择:(指的是我要使用的提供程序的大多数实现文档,而不是规范)

选项1-OpenID

  1. 客户端通过与任何外部提供商(Apple,Google,Facebook)登录获得auth_code
  2. 客户端将此auth_code发送到我的后端,该代码用于发出id_token
  3. 后端使用此id_token验证用户身份并存储有关该用户的所有必需信息
  4. 后端生成用于授权的访问/刷新令牌,并将其发送回客户端
  5. 现在我可以使用我的access_token进行授权,并使用刷新令牌进行auth-state-management(注销,使令牌无效)

问题-真的有问题吗?

  • 我不确定我是否需要经常检查用户是否仍然是有效身份。使用有效身份,我的意思是说外部身份(例如google用户)仍然存在,这基本上与我的持久层必须使该用户无效(删除)有关。换句话说,我是否必须将持久层与外部提供程序进行同步以避免死亡/无法使用的身份。如果诸如电子邮件地址之类的信息发生更改,而我的后端未收到有关此事的通知,则尤其会出现问题。还是我应该接受这样的事实,即我的后端中的用户只是通过id与外部用户相关,并且客户端必须自己在后端中管理其数据(例如,在客户端更改其电子邮件)。那意味着我最好忽略对外部用户数据(在提供者处)的任何更改。

选项2-OAuth

  1. 客户端通过与任何外部提供商(SiwA(ios),Google,Facebook)登录获得auth_code
  2. 客户端将此auth_code发送到我的后端,该代码用于从提供商处发出access_token / refresh_token
  3. 后端发回从外部提供程序获得的access_token / refresh_token
  4. 现在,每次客户端发出请求时,它都必须包含外部access_token,然后在后端使用该外部access_token询问外部提供程序此令牌是否有效,并且客户端可以访问资源。换句话说,我使用外部access_token进行授权
  5. 每次在后端都需要用户数据(例如电子邮件,地址...),有必要通过提供由客户端提供的access_token来向外部提供商询问此数据

问题/问题:

  • 我假设刷新过程必须在客户端执行,以防万一令牌过期,后端重定向了来自提供者的未经授权的重定向。那是正确的吗?
  • 我如何确定令牌来自哪个提供商。对我来说,实施一个反复试验过程并询问每个提供者是否有效的令牌似乎很奇怪。例如。如果后端在请求的标头中收到访问令牌,则它不知道要询问哪个提供程序。 (或者我应该将此信息编码在Bearer Provider Token这样的标头中,以便知道在哪里检查访问令牌。
  • 使用选项2 ,只要外部提供商遇到停机,任何用户都无法使用我的后端,而使用选项1 时,仅登录(初始值或显式后)退出,这会使刷新令牌无效)。

我有什么想念的吗?在我看来,选项2 给身份验证提供程序引入了许多不必要的通信,而选项1 确实忽略了可能需要的任何通信(例如,身份状态的同步) ? 对我来说,主要问题是,考虑选项1 (它似乎更适合我的情况),我是否必须对用户状态的任何状态变化(例如外部提供商的电子邮件更改)做出反应?忽略外部用户ID进行身份验证有任何弊端。

解决方法

我最终实现了OpenID,实现了我只需要身份验证,不需要授权或严格耦合用户数据。在问问题的时候,我意识到了差异,但是我没有对项目的需求进行深入的研究。由于我不需要外部资源的任何授权,因此我放弃了基本的OAuth协议。

关于OpenID,来自OpenID提供程序的外部身份管理不在协议范围之内,它必须独立完成。还有其他协议和方法处理例如SCIM

我最终依赖于id_token提供的外部id是唯一的事实,并在第一次进行身份验证(基本上是注册)时初始化了一次时间映射。从现在开始,我的服务器将管理用户数据。随后的认证请求依赖于以下事实:该映射永不改变,并且与保持在提供者处的任何数据相比,任何用户数据都可能不同,例如,与外部Identityl的Google邮件相比,我的服务器上的邮件地址不同。但这并不违反我的要求。

此外,我想补充一点,我最终支持隐式流和auth代码流,这意味着客户端可以直接发送id_token,而不是发送auth_code。我还没有完全弄清为什么这是不安全的,因为从我当前的角度来看,我的服务器要求提供者验证id_token,以通过提供错误的id_tokens来防止任何恶意意图。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。