如何在Postman集合中持久化OAuth2令牌(或使用刷新令牌)?

如何在Postman集合中持久化OAuth2令牌(或使用刷新令牌)?,oauth,oauth-2.0,postman,Oauth,Oauth 2.0,Postman,目标 能够在运行集合之前运行集合,而无需逐个完成每个调用的授权过程 我所尝试/注意到的 在Postman中使用OAuth2 authorization helper时,我没有发现保存返回的刷新令牌的方法,因此在访问令牌过期时使用它来获取新的刷新令牌。(我建议将此功能放置在Postman Github问题中的帮助器中。) 我尝试在集合开始时创建几个步骤来复制帮助器,但无法通过需要用户交互才能批准/拒绝的步骤(这是有道理的,否则会带来安全风险)。然而,我似乎也不知道如何像OAuth2助手那样提示用户

目标

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

我所尝试/注意到的

  • 在Postman中使用OAuth2 authorization helper时,我没有发现保存返回的刷新令牌的方法,因此在访问令牌过期时使用它来获取新的刷新令牌。(我建议将此功能放置在Postman Github问题中的帮助器中。)

  • 我尝试在集合开始时创建几个步骤来复制帮助器,但无法通过需要用户交互才能批准/拒绝的步骤(这是有道理的,否则会带来安全风险)。然而,我似乎也不知道如何像OAuth2助手那样提示用户

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

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

    旁注:我一直在使用Postman mac客户端,以防我不知道的客户端中存在不同的问题。

    我找到了答案

    首先,设置以下环境变量:

    • url
      :(您的API端点)
    • 访问令牌
      :(空白)
    • 刷新\u令牌
      :(空白)
    • 客户id
      :(您的客户id)
    • 客户机密
      :(您的客户机密)
    • 用户名
      :(您的用户名)
    • 密码
      :(您的密码)
    接下来,创建一个新呼叫,使用
    密码
    授权类型
    获取
    访问\u令牌

    在我的例子中,我发布到
    {{url}/access\u token
    。与此调用一起发送的是以下信息,如正文选项卡中指定的
    表单数据
    键/值对:

    • 授权类型
      密码
    • username
      {{{username}}
    • 密码
      {{{password}
    • client\u id
      {{{client\u id}
    • client\u secret
      {{{client\u secret}
    发送此帖子将导致类似以下响应:

    {
      "access_token": "kciOMpcmRcGTKfoo",
      "token_type": "Bearer",
      "expires_in": 3600,
      "refresh_token": "DMGAe2TGaFbar"
    }
    
    然后,在Tests选项卡中,我添加了以下代码来分配两个环境变量,
    access\u-token
    refresh\u-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\u令牌
    作为如下环境变量:
    {{access\u令牌}
    。在我的例子中,我转到调用/测试中的Headers选项卡并添加此密钥/密钥对:

    • 授权
      承载{{{access\u token}}
    优点:这里我没有给出示例,但理论上我可以添加一个预请求脚本,根据API测试当前(非空)
    access\u令牌
    ,如果失败,使用给定(非空)
    refresh\u令牌
    获取一个新的。这样我就不用担心访问令牌过期了

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


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

    好,首先输入OAUTH令牌URL,单击Body选项卡,并填写以下POST参数: 客户端id、授权类型、用户名、密码、覆盖

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

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

    然后输入一个应用程序URL,单击Headers选项卡,并输入一个带有值承载{{access_token}的参数Authorization。然后点击发送


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

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

    示例代码 我在这里作了一个要点

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

    注:有4种类型的补助金
    // 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);
    });