通过CLI的Zapier刷新令牌会引发错误

时间:2018-09-21 11:53:10

标签: zapier-cli

我已经在Zapier的示例代码库上构建了Zapier应用。一切进展顺利,希望获得刷新令牌。我在Postman中进行了刷新,并且正在使用完全相同的代码。首先使用access_token非常有效,而且在连接后的前10分钟进行帐户连接测试也很有效。之后,令牌到期,我希望zapier自动刷新它。

为什么当access_token和refresh_token API的uri和方法相同时,服务器会继续给我提供401代码,只是主体不同,但是基于邮递员的调用,这应该可以正常工作。

const to_json = require('xmljson').to_json;

const getAccessToken = (z, bundle) => {
  const promise = z.request(`${process.env.BASE_URL}/oauth2/token`, {
    method: 'POST',
    body: {
      //extra data pulled from the users query string
      //accountDomain: bundle.cleanedRequest.querystring.accountDomain,
      code: decodeURI(bundle.inputData.code),
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
      redirect_uri: '{{bundle.inputData.redirect_uri}}',
      grant_type: 'authorization_code'
    },
    headers: {
      'content-type': 'application/x-www-form-urlencoded'
    }
  });

  // Needs to return at minimum, `access_token`, and if your app also does refresh, then `refresh_token` too
  return promise.then((response) => {
    if (response.status !== 200) {
      throw new Error('Unable to fetch access token: ' + response.content);
    }

    const result = JSON.parse(response.content);

    return {
      access_token: result.access_token,
      refresh_token: result.refresh_token
    };
  });
};

const refreshAccessToken = (z, bundle) => {
  const promise = z.request(`${process.env.BASE_URL}/oauth2/token`, {
    method: 'POST',
    body: {
      //extra data pulled from the users query string
      //accountDomain: bundle.cleanedRequest.querystring.accountDomain,
      refresh_token: bundle.authData.refresh_token,
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
      redirect_uri: '{{bundle.inputData.redirect_uri}}',
      grant_type: 'refresh_token'
    },
    headers: {
      'content-type': 'application/x-www-form-urlencoded'
    }
  });

  // Needs to return at minimum, `access_token`, and if your app also does refresh, then `refresh_token` too
  return promise.then((response) => {
    if (response.status !== 200) {
      throw new Error('Unable to refresh access token: ' + response.content);
    }

    const result = JSON.parse(response.content);

    return {
      access_token: result.access_token,
      refresh_token: result.refresh_token
    };
  });
};

const testAuth = (z , bundle) => {
  // Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that
  // every user will have access to, such as an account or profile endpoint like /me.
  const promise = z.request({
    method: 'GET',
    url: `${process.env.BASE_URL}/v1/888330/crm/Accounts`,
  });

  // This method can return any truthy value to indicate the credentials are valid.
  // Raise an error to show
  return promise.then((response) => {
    if (response.status === 401) {
      throw new Error('The access token you supplied is not valid');
    }

    to_json(response, function (error, data) {

      const response = data;
    });

    return response.content;
  });
};

module.exports = {
  type: 'oauth2',
  oauth2Config: {
    // Step 1 of the OAuth flow; specify where to send the user to authenticate with your API.
    // Zapier generates the state and redirect_uri, you are responsible for providing the rest.
    // Note: can also be a function that returns a string
    authorizeUrl: {
      url: `${process.env.BASE_URL}/oauth2/auth`,
      params: {
        client_id: '{{process.env.CLIENT_ID}}',
        state: '{{bundle.inputData.state}}',
        redirect_uri: '{{bundle.inputData.redirect_uri}}',
        response_type: 'code'
      }
    },
    // Step 2 of the OAuth flow; Exchange a code for an access token.
    // This could also use the request shorthand.
    getAccessToken: getAccessToken,
    // (Optional) If the access token expires after a pre-defined amount of time, you can implement
    // this method to tell Zapier how to refresh it.
    refreshAccessToken: refreshAccessToken,
    // If you want Zapier to automatically invoke `refreshAccessToken` on a 401 response, set to true
    autoRefresh: true
    // If there is a specific scope you want to limit your Zapier app to, you can define it here.
    // Will get passed along to the authorizeUrl
    // scope: 'read,write'
  },
  // The test method allows Zapier to verify that the access token is valid. We'll execute this
  // method after the OAuth flow is complete to ensure everything is setup properly.
  test: testAuth,

  // assuming "username" is a key returned from the test
  connectionLabel: ''
};

API的资源在这里:https://support.exactonline.com/community/s/knowledge-base#All-All-DNO-Content-oauth-eol-oauth-dev-step4

Zapier引发的错误:

What happened (You are seeing this because you are an admin):
  Starting POST request to https://start.exactonline.nl/api/oauth2/token/
  Received 401 code from https://start.exactonline.nl/api/oauth2/token/ after 132ms
  Received content "<html><head><title>Object moved</title><script type="text/javascript" src="/ruxitagentjs_ICA27SVafgh"
  Got 401 calling POST https://start.exactonline.nl/api/oauth2/token/, triggering auth refresh.
Console logs:
Stack trace:
  throwForStaleAuth (/var/task/node_modules/zapier-platform-core/src/http-middlewares/after/throw-for-stale-auth.js:10:11)
  Object.collector.then.newOutput (/var/task/node_modules/zapier-platform-core/src/middleware.js:80:37)
  bound (domain.js:301:14)
  Object.runBound (domain.js:314:12)
  Object.tryCatcher (/var/task/node_modules/bluebird/js/release/util.js:16:23)
  Promise._settlePromiseFromHandler (/var/task/node_modules/bluebird/js/release/promise.js:512:31)
  Promise._settlePromise (/var/task/node_modules/bluebird/js/release/promise.js:569:18)
  Promise._settlePromise0 (/var/task/node_modules/bluebird/js/release/promise.js:614:10)
  Promise._settlePromises (/var/task/node_modules/bluebird/js/release/promise.js:693:18)
  Async._drainQueue (/var/task/node_modules/bluebird/js/release/async.js:133:16)
  Async._drainQueues (/var/task/node_modules/bluebird/js/release/async.js:143:10)
  Immediate.Async.drainQueues (/var/task/node_modules/bluebird/js/release/async.js:17:14)
  runCallback (timers.js:794:20)
  tryOnImmediate (timers.js:752:5)
  processImmediate [as _immediateCallback] (timers.js:729:5)

0 个答案:

没有答案