如何在Postman集合中保留OAuth2令牌(或使用刷新令牌)?

时间:2016-01-28 20:00:02

标签: oauth oauth-2.0 postman

目标

在运行集合之前,无需单独执行每个调用的授权过程即可运行集合。

我尝试/注意到的内容

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

  2. 我尝试在集合的开头创建一些步骤来复制帮助程序,但是无法通过需要用户交互来批准/拒绝的步骤(这很有意义,因为它&#39 ;否则存在安全风险)。但是,我似乎无法弄清楚如何以OAuth2助手的方式提示用户。

  3. 我已经将我的期望提高了一小部分,因为刷新令牌并认为我可以在列表中的第一个测试中运行身份验证,以某种方式在全局或环境变量中保存访问令牌,然后在所有后续测试中使用该令牌,但我还没有找到一种方法来保存通过OAuth2助手生成的访问令牌。

  4. 我很想知道是否有一个解决方案,这使得集合能够以最小的努力运行授权。对于所有使用OAuth2授权的集合中编写的更多测试,这变得更加重要。

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

4 个答案:

答案 0 :(得分:36)

好的,首先输入您的OAUTH令牌URL,单击Body选项卡,然后填写以下POST参数: client_id,grant_type,username,password,override。

enter image description here

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

swap!

enter image description here

然后输入一个应用程序URL,单击“标题”选项卡,然后输入带有值Bearer {{access_token}}的参数Authorization。然后单击“发送”。

enter image description here

瞧!

答案 1 :(得分:14)

我找到了答案here on github

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

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

接下来,使用access_token password创建一个获得grant_type的新来电。

在我的情况下,我发布到{{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调用/测试,但确实可以获得自动化的好处,非交互式测试,具有自行运行子文件夹或整个集合的灵活性。

答案 2 :(得分:1)

其他答案都是正确的。但是,还有另一种方法可以完成此操作,而不需要任何额外的请求。 此方法使用需要pre-request的请求的access_token脚本。 您可以使用postman-sandbox-api

中记录的pm.sendRequest

从请求前脚本中发送一个请求到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,您可以在变量中使用该变量,如下所示: enter image description here

注意:Oauth2中有4种类型的授权类型。其中两个(Auth code和Implicit)需要与浏览器进行交互,而该交互无法自动化。但是,如果服务器提供了刷新令牌,则以上脚本可以帮助您获取访问令牌。其他两种类型(客户端凭据和密码凭据)不需要任何浏览器交互。因此,可以从脚本中自动执行这些操作。如果您使用client_credentials,则可以调整上面的脚本以从code获取authUrl,然后从access_token获取AuthTokenUrl

答案 3 :(得分:0)

首先,从线程中read this answer。现在,考虑这个问题的后半部分(基于评论):

如何使用刷新令牌?

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

enter image description here

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

enter image description here

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

enter image description here

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

HTH!