oAuth2.0:为什么需要“授权代码”而只需要令牌?

时间:2013-03-05 08:26:42

标签: oauth-2.0

使用oAuth 2.0,在“授权代码”授权授权中,我首先调用“/ authorize”,获取代码,然后在“/ token”调用中使用此代码来获取访问令牌。 / p>

我的问题:为什么这是流程?我想这是出于安全原因,但我无法弄明白。为什么实现是这样的,并且在第一次调用(“/ authorize”)之后没有立即获取访问令牌?

为什么我们需要这个代码?

6 个答案:

答案 0 :(得分:9)

授权代码流程适用于涉及3方的情况。

这些政党是:

  • <强>客户端

    用户使用他的网络浏览器。他想使用你的申请。

  • <强>提供商

    有关于用户的信息。如果有人想要访问此数据,则用户必须先同意。

  • 您的(网络)应用

    想要从提供商处访问有关用户的信息。

现在您的应用用户说明(将其浏览器重定向到/authorize端点):

  

嘿用户,这是我的客户端ID 。请与提供商联系并授权他直接与我交谈。

所以用户提供商对话(请求授权代码并通过在浏览器中打开回调网址将其返回到您的应用):

  

嘿,提供商,我想使用这个应用程序,所以他们需要访问我的数据。给我一些代码,然后将此代码提供给应用程序。

现在您的应用拥有客户端提供商已知的授权码。通过将其交给提供商,您的应用现在可以证明,客户端允许访问其数据。 提供商现在向您的(网络)应用发出访问令牌,因此您的(网络)应用每次都不必重做这些步骤(至少暂时)

如果您的应用直接在客户端运行的其他应用类型(例如iPhone / Android应用或Javascript客户端),则中间步骤是多余的。

答案 1 :(得分:6)

是否也可以通过让这个中间步骤阻止客户端看到访问令牌?

来自O'Reilly的书:

  

授权代码此授权类型最适合服务器端Web应用程序。在资源拥有者之后   授权访问他们的数据,他们被重定向回网络   应用程序使用授权代码作为查询参数   URL。客户端必须将此代码交换为访问令牌   应用。这种交换是在服务器到服务器上完成的并且需要   client_id和cli ent_secret,甚至阻止资源   所有者获取访问令牌。此授权类型也允许   使用刷新令牌对API进行长期访问。

     

基于浏览器的客户端应用程序的隐式授权隐式授权是所有流中最简单的,并且已经过优化   用于在浏览器中运行的客户端Web应用程序。资源   所有者授予对应用程序的访问权限,并且新的访问令牌是   立即铸造并使用#hash传回应用程序   URL中的片段。该应用程序可以立即提取   从散列片段(使用JavaScript)访问令牌并制作API   要求。此授权类型不需要中介   “授权代码”,但它也没有提供刷新   长期访问的令牌。

更新 - 确实如此:

  

何时应使用授权码流?授权   

时应使用代码流      
      
  • 需要长期访问。

  •   
  • OAuth客户端是一个Web应用程序服务器。

  •   
  • API调用的问责制非常重要,OAuth令牌不应泄露给用户可以访问的浏览器   它

  •   

更多:

  

也许最重要的是 - 因为永远不会发送访问令牌   通过浏览器 - 访问令牌的风险较小   通过浏览器历史记录泄漏到恶意代码,referer标题,   JavaScript等。

答案 2 :(得分:5)

客户端数据通常被认为是不安全的。对于在初始步骤中授予令牌的隐式调用,具有access_token的任何人都可以请求数据,API不知道谁在调用该API。

但是,对于应用程序想要识别自身的Web服务器应用程序,带有client_secret的client_id与authorization_code一起发送以获取access_token,以后可以独立发送。

假设,如果最初授予access_token本身,那么client_id和access_token仍将被视为公开,因此除了access_token之外,应用还必须每次发送client_secret以确保该请求确实来自它。

在当前场景中,在获取access_token之后,可以独立进行更多请求而无需client_secret。

答案 3 :(得分:0)

重要的一点是

  

也许最重要的是 - 因为访问令牌永远不会通过浏览器发送 - 访问令牌通过浏览器历史记录,引用标头,JavaScript等泄露给恶意代码的风险较小。

答案 4 :(得分:0)

我认为是这样的;

当我们使用授权码时,我们有2个验证部分;

  • 1;验证用户的所有权,因为他登录
  • 2;我们知道客户端,他说的确是他,因为客户端正在发送他的client_secret。

因此,如果我们在用户进行身份验证而不是授权代码时返回访问令牌,我们知道是请求它的用户,但我们不知道它将用于已注册的客户端。例如,您的webapp。

当我们使用'隐式授权'; (或返回访问令牌而不是授权代码)

  • 1;我们知道正是用户正在接收访问令牌,但是没有必要获取授权代码,因为基于“用户代理”的应用程序是不可检查的。它是可检查的,如果你考虑它,但它可用于每个人。 client_secret可以在“基于用户代理”的应用程序的源代码中公开查看,因此每个人都可以“查看源代码”并复制client_secret并使用此方法来验证客户端的所有权。

答案 5 :(得分:0)

@ksht 的回答基本正确。对于那些寻找简单、简短的答案的人来说,是这样的:

因为客户端应用程序(浏览器或本机应用程序)可能会拦截所传递的令牌。 oauth 隐式 流程确实允许这样做,但仅限于非常特殊的情况。在所有其他情况下,浏览器可能会泄漏信息(操作系统中的黑客、浏览器错误、插件),或者对于本机应用程序,您可以拦截将重定向 URL 映射到应用程序的自定义 URL 方案。因此,解决方法是发回代码而不是令牌(通过 tls)并使用 PKCE 来确保代码可以安全地交换为令牌。