【问题标题】:How to persist an OAuth2 token (or use a refresh token) in Postman collections?如何在 Postman 集合中保留 OAuth2 令牌(或使用刷新令牌)?
【发布时间】:2016-05-06 09:12:32
【问题描述】:

目标

能够运行一个集合,而无需在运行集合之前单独完成每个调用的授权过程。

我尝试过/注意到的事情

  1. 在 Postman 中使用 OAuth2 授权助手时,我还没有发现一种方法来保存返回的刷新令牌,因此在访问令牌过期时使用它来获取新令牌。 (我建议将此功能放在 Postman Github 问题中的帮助程序中。)

  2. 我尝试在集合的开头创建几个步骤来复制帮助程序,但无法通过需要用户交互来批准/拒绝的步骤(这是有道理的,否则会存在安全风险)。但是,我似乎也不知道如何提示用户,就像 OAuth2 帮助程序那样。

  3. 我对刷新令牌的期望降低了一个档次,并认为我可以简单地在列表中的第一个测试上运行身份验证,以某种方式将访问令牌保存在全局或环境变量中,并且然后在所有后续测试中使用该令牌,但我还没有找到保存通过 OAuth2 助手生成的访问令牌的方法。

我很想知道是否有解决方案可以使集合能够以最少的授权运行。随着在一个集合中编写的测试越多,所有测试都使用 OAuth2 授权,这一点变得更加重要。

旁注:我一直在使用 Postman mac 客户端,以防我不知道的客户端有所不同。

【问题讨论】:

    标签: oauth oauth-2.0 postman


    【解决方案1】:

    好的,首先输入您的 OAUTH 令牌 URL,单击“正文”选项卡,然后填写以下 POST 参数: client_id、grant_type、用户名、密码、覆盖。

    然后,单击“测试”选项卡,输入此文本,然后按“发送”:

    var data = JSON.parse(responseBody);
    postman.setGlobalVariable("access_token", data.access_token);
    postman.setGlobalVariable("refresh_token", data.refresh_token);
    

    然后输入您的应用程序 URL,单击 Headers 选项卡,然后输入参数 Authorization,其值为 Bearer {{access_token}}。然后点击发送。

    瞧!

    【讨论】:

    • 谢谢您,您的回答很棒!您能否通过举例说明如何使用 refresh_token 来完成它。
    • 是的,令人惊叹的答案,赞成...如果你能包括一个 refres_token 的例子,那就太棒了
    • 我有一个类似的 grant_type = client_credentials 配置,效果很好。但是现在我有一个案例需要使用grant_type=authorization_code。对于这个,这个解决方案不起作用,因为必须显示一个登录弹出窗口..这种情况有解决方案吗?
    • 在我的情况下,我得到一个 pm.setGlobalVariable() not found 错误。用 postman.setGlobalVariable() 修复
    【解决方案2】:

    首先,来自线程的read this answer。现在,考虑这个问题的后半部分(基于 cmets):

    如何使用刷新令牌?

    1. 创建一个新的 POST 请求(最容易复制您为获取 access_token 而创建的请求)。

    1. 在正文中,删除usernamepassword。将grant_type 替换为“refresh_token”。添加带有值“{{refresh_token}}”的refresh_token,这是对您第一次授权时创建的变量的引用(您还记得read this answer吗?

    1. 确保刷新请求的测试部分覆盖 access_token 和 refresh_token 的 Postman 变量。为什么?因为每当您执行刷新时,您都会获得另一个刷新令牌。如果您没有捕获新的刷新令牌,您最终将使用旧的刷新令牌,API 将拒绝它。然后,您需要从第一步(即来自this answer)重新运行整个过程。

    1. 现在,当您的授权到期时,您无需运行包含您的用户名和密码的原始请求。您可以使用我们刚刚创建的请求永久刷新。当您正在协作并需要共享 API 访问权限但又不想共享用户名/密码时,这尤其有用。

    HTH!

    【讨论】:

      【解决方案3】:

      其他两个答案都是正确的。但是,还有另一种方法可以做到这一点,并且不需要任何额外的请求。 此方法使用需要access_token 的请求的pre-request 脚本。 您可以使用pm.sendRequest 中记录的postman-sandbox-api

      从预请求脚本只需向 auth-token URL 发送一个请求。发送所有凭据和刷新令牌。在响应中,您将获得访问令牌,然后您可以将其保留在环境中或仅在内存中,然后使用它。

      示例代码 我在这里做了一个要点https://gist.github.com/harryi3t/dd5c61451206047db70710ff6174c3c1

      // Set all these variables in an environment or at collection level
      let tokenUrl = pm.variables.get('tokenUrl'),
          clientId = pm.variables.get('clientId'),
          clientSecret = pm.variables.get('clientSecret'),
          refreshToken = pm.variables.get('refreshToken'),
          requestOptions = {
            method: 'POST',
            url: tokenUrl,
            body: {
              mode: 'formdata',
              formdata: [
                  {
                      key: 'grant_type',
                      value: 'refresh_token'
                  },
                  {
                      key: 'client_id',
                      value: clientId
                  },
                  {
                      key: 'client_secret',
                      value: clientSecret
                  },
                  {
                      key: 'refresh_token',
                      value: refreshToken
                  }
              ]
            }
          };
      
      console.log({ requestOptions });
      
      pm.sendRequest(requestOptions, (err, response) => {
        let jsonResponse = response.json(),
            newAccessToken = jsonResponse.access_token;
      
        console.log({ err, jsonResponse, newAccessToken })
      
        // If you want to persist the token
        pm.environment.set('accessToken', newAccessToken);
      
        // Or if you just want to use this in the current request and then discard it
        pm.variables.set('accessToken', newAccessToken);
      });
      

      现在,当发送请求时,变量accessToken 将出现,您可以在请求中使用它,如下所示:

      注意:Oauth2 中有 4 种授权类型。其中两个(身份验证代码和隐式)需要与无法自动化的浏览器交互。但是如果服务器提供了 refresh-token,那么上面的脚本可以帮助你获取 access-token。其他两种类型(客户端凭据和密码凭据)不需要任何浏览器交互。所以这些可以从脚本中自动化。如果您使用的是 client_credentials,则可以调整上述脚本以从 authUrl 获取 code,然后从 AuthTokenUrl 获取 access_token

      【讨论】:

      • 我喜欢使用预请求脚本的想法,但您是否必须在每个请求中配置脚本?有没有办法为每个环境执行一个脚本?
      • 这些请求是否与不同的身份验证服务器(如 Google 和 Github)通信并需要不同的令牌?如果是,那么是的,您将不得不复制代码。否则,您可以将令牌存储在变量中并重复使用。
      • @nettie old,但以防万一:您可以将预请求脚本存储在集合中,该脚本用于该集合中发出的每个请求。
      【解决方案4】:

      我找到了答案here on github

      首先,设置这些环境变量:

      • url:(您的 API 端点)
      • access_token:(空白)
      • refresh_token:(空白)
      • client_id : (你的 client_id)
      • client_secret : (你的 client_secret)
      • username : (你的用户名)
      • password : (你的密码)

      接下来,使用password grant_type 创建一个新的调用,获取access_token

      就我而言,我发帖到{{url}}/access_token。与此调用一起发送的是以下信息,即“正文”选项卡中指定的 form-data 键/值对:

      • grant_typepassword
      • username : {{username}}
      • password : {{password}}
      • client_id : {{client_id}}
      • client_secret{{client_secret}}

      发送这个 POST 会产生类似这样的响应:

      {
        "access_token": "kciOMpcmRcGTKfoo",
        "token_type": "Bearer",
        "expires_in": 3600,
        "refresh_token": "DMGAe2TGaFbar"
      }
      

      然后,在“测试”选项卡中,我添加了以下代码来分配两个环境变量,access_tokenrefresh_token

      var data = JSON.parse(responseBody);
      postman.setEnvironmentVariable("access_token", data.access_token);
      postman.setEnvironmentVariable("refresh_token", data.refresh_token);
      

      注意:我还在那里进行了测试,只是为了确保至少这个调用也能正常工作,尽管这与原来的问题无关:

      var jsonData = JSON.parse(responseBody);
      tests["token_type is Bearer"] = jsonData.token_type === "Bearer";
      

      现在我创建的任何新调用都可以使用第一次调用生成的access_token 作为环境变量,如下所示:{{access_token}}。就我而言,我在调用/测试中转到 Headers 选项卡并添加此密钥/对:

      • AuthorizationBearer {{access_token}}

      加分:我在这里没有给出示例,但理论上我可以添加一个预请求脚本,针对 API 测试当前(非空白)access_token,如果失败,获取一个新脚本使用给定的(非空白)refresh_token。这样我就不用担心访问令牌过期了。

      总而言之,我不喜欢这个解决方案,因为它需要将第一个 access_token 调用添加到我的集合中的每个子文件夹,因为如果我只想运行一个子文件夹而不是整个集合,我需要确保我有一个新的 access_token。不这样做意味着当 access_token 过期时所有测试都会失败。如果您从未在 Collection Runner 中单独运行子文件夹,则只需创建一个 access_token 调用并将其设置为在集合中运行的第一个调用即可。

      但是,出于这个原因,我还不打算将此标记为正确答案。我猜有一个比我想出的更好的答案 - 理想情况下,我不必将相同的 access_token 调用/测试复制到每个子文件夹中,但确实可以获得自动化、非交互式的好处测试可以灵活地运行子文件夹本身或整个集合。

      【讨论】:

      • 已经有一段时间了,由于没有其他人回答,我将其标记为正确。
      • 我对“测试”选项卡以及它如何与我的通话联系感到迷失。
      猜你喜欢
      • 2017-05-29
      • 2021-06-19
      • 2017-04-20
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 2017-12-13
      • 2012-07-21
      • 2019-06-28
      相关资源
      最近更新 更多