提问人:aborted 提问时间:6/1/2016 最后编辑:Communityaborted 更新时间:6/12/2016 访问量:3426
使用自己的 API for web 应用 - 使用 OAuth2 的身份验证过程
Consuming own API for web app - Authentication process with OAuth2
问:
概述
我目前正在为一个图像共享应用程序创建一个 API,该应用程序将在 Web 上运行,并将在未来的某个时候在移动设备上运行。我了解 API 构建的逻辑部分,但我仍然在努力满足我自己对身份验证部分的要求。
因此,我的 API 必须可供全世界访问:那些具有访客访问权限的人(例如,未登录的人可以上传),以及注册用户。因此,当注册用户上传时,我显然希望用户信息与请求一起发送,并通过数据库中的外键将该用户信息附加到上传的图像上。
通过 OAuth2 进行身份验证 - 实现
我已经知道 OAuth2 是 API 身份验证的必经之路,所以我将实现这个,但我真的很难弄清楚如何处理我的情况。我想到使用授权并为我的 Web 应用程序仅生成一组凭据,并让它向 API 发送请求以获取访问令牌并让用户执行操作。用户注册过程本身将由此授权处理。client credentials
client secret
但是,当用户注册并登录时呢?我现在如何处理身份验证?这需要另一笔赠款来接管吗?我正在考虑在用户登录期间执行一些授权过程,以生成新的访问令牌。这种方法错了吗?
我需要什么帮助
我需要您就如何正确处理我的案例的身份验证流程提供意见。这种双向身份验证过程可能不是我需要的,但这是我理解它的方式。非常感谢您的支持。
答:
你的方法似乎可行。
Oauth2 有 4 个主要部分:
- 资源服务器(您的 API)Resource Server (your API)
- 资源所有者(在资源服务器上拥有数据的最终用户)
- 授权服务器(获取授权并颁发令牌)
- 客户端(你的 Web 应用 - 以及未来的应用)Client (your web app - and future apps)
请记住,使用客户端凭据授予时,颁发的令牌可能没有任何用户上下文。因此,如果您的 API 端点依赖于令牌中包含的用户标识符/资源所有者,则需要针对此类令牌进行编码。
如果您确实需要令牌来为您的 API 提供一些资源所有者上下文,并且您的 Web 应用程序恰好是您的身份提供商,那么您可以使用资源所有者密码授予,这将在资源所有者/用户的上下文中为您提供令牌和刷新令牌。
授权代码授予是可以的,前提是你未来的 API 使用者是 Web 应用程序(即在服务器上运行)。如果您计划允许移动/本机应用程序使用您的 API,则应考虑在授权服务器中允许隐式授权。
如果您的 API 没有最终用户,并且每个客户端对 API 的访问权限各不相同,具体取决于它是什么应用,则可以使用 client-credentials 授予和使用范围来限制 API 访问。
编辑
因此,我的 API 必须可以通过访客访问(非 例如,登录的人可以上传)和注册用户。所以 当注册用户上传时,我显然希望该用户被发送 以及请求,并将该用户附加到上传的图像
为此,您的 API 上传终端节点可以处理 Oauth2.0 持有者令牌,但不依赖于它们。例如,端点可以被任何人使用,那些在标头中提供访问令牌的人将把他们的上传与API从令牌中获取的用户上下文相关联。 然后,如果需要,可以使其他终结点依赖于令牌。
根据评论进行编辑
注册过程本身将使用客户端凭据授予, 正确?
我不认为注册过程本身应该成为受 Oauth 保护的资源。理想情况下,注册应由您的身份提供商(例如 google、facebook 或您自己的用户会员数据库)处理。Oauth2.0 的一个优点是,它消除了 API 必须执行用户管理工作的需要。
评论
实际上,您并不需要 oauth 来对自己的 API 进行身份验证。
如果您希望其他应用程序访问您的 API,OAuth2 非常有用。
让我稍微解释一下 OAuth2 是如何工作的:
- 客户端(应用程序)想要使用您的 API,因此您向他提供客户端凭据(client_token 和 client_secret)。然后,在数据库中设置一组客户端可以使用的重定向位置。
- 客户需要用户授权才能代表用户使用您的 API。因此,客户端将用户发送到您网站上的 URL(带有客户端需要的client_token范围 [您定义不同范围的含义]、重定向 uri 和response_type [oauth2 定义了不同的response_type但让我们专注于“代码”])
- 用户登录到您的站点,并接受代表用户授予对客户端的 API 访问权限。当用户接受此授权时,你将生成授权(授权包含用户的信息、请求的凭据 [scope] 以及可以“声明”授予访问权限的客户端)。
- 然后,用户将被重定向到客户端请求的redirect_uri(当客户端将用户发送到您的身份验证站点时),并在 URL 参数中包含授权代码(它只是一个 ID)。
- 在此阶段,客户端将向您的 API 发出请求,提供授权代码、他自己的client_token、client_secret和grant_type (authorization_code),他将获得以下响应:authorization_token、refresh_token、token_type(在本例中为 Bearer)、expires_in(过期时间(以秒为单位)和范围。
- 完成所有这些操作后,客户端将能够使用access_token代表用户向 API 发出请求,直到令牌过期。令牌过期后,客户端必须使用refresh_token(而不是授权代码)请求新的access_token。
评论
iandayman 的回答有很多很好的信息,但我认为一个更狭窄、更具体的答案可能会对您有所帮助。
因此,对于初学者来说,客户端凭据授予不适合您。如果我们查看 OAuth2 规范,则客户端凭据授予用于
当授权范围为 仅限于客户端控制下的受保护资源...当客户代表自己行事时
这不适合您,原因有两个。
首先,您的客户无法控制任何受保护的资源。您正在访问的所有资源要么不受保护(未登录的人员上传),要么由最终用户控制。此外,您不能在浏览器中保留机密(例如客户端机密);应用程序的任何用户都可以使用浏览器的开发人员工具来查看和破坏机密。
其次,正如我所提到的,客户从不代表自己行事。它始终代表可能已登录也可能未登录的用户执行操作。
您需要资源所有者密码凭据授予。
当用户未登录时(就像您提到的上传一样),您只是没有授权。当用户登录时,您可以将其凭据发送到授权服务器。如果密码与用户名匹配,则授权服务器将创建一个令牌,并保留从该令牌到用户的映射,并返回该令牌。然后,每当您的客户端对登录用户发出另一个请求时,您都会将该令牌放在标头中。在后端,您说“如果授权标头中有令牌,请找出它对应的用户,并将其与此上传相关联(或检查是否允许上传)”。Authorization
用户注册如何进行?很简单,你发布一些用户对象,比如
name: jim beam
username: jimb
password: correct horse battery staple
到您的用户创建终结点(或其他)。生成 salt 并对密码进行哈希处理,然后将用户信息与 salt 和 hash 一起存储在数据库中。此端点上没有任何授权。POST /users
希望这更符合您的要求。
评论
上一个:变量前面的感叹号 - 需要澄清
下一个:提交后保留字段值
评论