MONEI / Shopify-api-node

Node Shopify connector sponsored by MONEI
https://monei.com/shopify-payment-gateway/
MIT License
952 stars 280 forks source link

302 redirect to https://shop/password when requesting resource #446

Closed axmachina closed 3 years ago

axmachina commented 3 years ago

Doing exact same request with the exact same access token works fine:

await fetch(
      `https://${shop}/admin/api/2020-04/shop.json`,
      {
        method: "get",
        headers: {
          "Content-Type": "application/json",
          "X-Shopify-Access-Token": token,
        },
      }
    )
      .then((res) => {
        return res.json()
      })
      .then((json) => {
        console.log(json);
      });

But when I attempt to make the same exact request using shopify-api-node, it fails with MaxRedirectsError error.

shopify = new Shopify({
      shopName: shop,
      accessToken: token,
      apiVersion, // 2020-10 
    });

shopify.shop
      .get()
      .then((data) => {
        console.log("Shop", data);
      })
      .catch((error) => {
        console.error(error);
      });

Note that Shopify() used to work just fine for me until recently. There were no changes to my code that would explain the discrepancy in behaviour. Examining shopify-api-node request, it appears its sending all the correct bits using the got lib.

What could I be missing here?

bluebeel commented 3 years ago

I got the same error. Doing the same request with postman or fetch give me the response but using the lib i get a MaxRedirectsError: Redirected 10 times. Aborting

lpinca commented 3 years ago

Sounds like a bug in got, the HTTP library used by shopify-api-node. Can you try and see if you get the same error using got directly?

axmachina commented 3 years ago

Sounds like a bug in got, the HTTP library used by shopify-api-node. Can you try and see if you get the same error using got directly?

I'm working on it now. Got seems to be all over the place.

axmachina commented 3 years ago

I found that both node-fetch and https.request work as expected.

let apiUriShop = `https://${shop}/admin/api/2020-04/shop.json`;

    let headers = {
      "Content-Type": "application/json",
      "X-Shopify-Access-Token": token,
    };

    await fetch(apiUriShop, {
      method: "get",
      headers,
    })
      .then((res) => {
        return res.json();
      })
      .then((json) => {
        console.log(json);
      })
      .catch((error) => {
        console.error(error);
      });

    const httpsReq = https.request({
      hostname: shop,
      port: 443,
      path: "/admin/api/2020-04/shop.json",
      method: "GET",
      headers
    }, (res) => {
      console.log('statusCode:', res.statusCode);
      console.log('headers:', res.headers);
      res.setEncoding("utf8");
      let data = "";
      res.on('data', (d) => { // Buffer
        data += d.toString();
      });

      res.on('end', () => {
        console.log(`https.request done`, data);
      });
    });
    httpsReq.on('error', (e) => {
      console.error('https.request error', e);
    })
    httpsReq.end();

However, got fails with infinite redirects.

 const gotResult = await got
      .get(gotUri, {
        headers,
        timeout: 60000,
        retry: 0,
        method: "GET",
        hooks: {
          beforeRequest: [
            (options) => {
              console.log(`Before request`, options);
            },
          ],
          beforeRedirect: [
            (options, response) => {
              console.log(
                `Before redirect: ${response.req.path} => ${response.headers.location}\nRequest:\n${response.req._header}`
              );
            },
          ],
          afterResponse: [
            (res) => {
              console.log(`After response`, res);
              return res;
            },
          ],
        },
      })
      .catch((error) => {
        console.error(error);
      });
    console.log(gotResult);

The most likely culprit is that got doesn't appear to be constructing https.request correctly which causes it to send a request to GET "/" and not "/admin/api/2020-04/shop.json" as both fetch and https.request do normally:

GET / HTTP/1.1
Content-Type: application/json
X-Shopify-Access-Token: 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
Host: DEVSHOP.myshopify.com

This results in shopify /password redirect for store owner login.

I'm trying to figure out just why got is failing to construct proper https.request however.

lpinca commented 3 years ago

@axmachina I can't reproduce.

$ node -v
v15.4.0
shopify@ /Users/luigi/shopify
`-- shopify-api-node@3.5.4
$ cat index.js 
'use strict';

const Shopify = require('shopify-api-node');

const shopify = new Shopify({
  shopName: 'quuz',
  accessToken: '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'
});

(async function () {
  const shop = await shopify.shop.get();
  console.log(shop);
})().catch(console.error);
$ node index.js 
{
  id: 19563841,
  name: 'quuz',
  email: 'al.bino@rocketmail.com',
  domain: 'quuz.myshopify.com',
  province: 'Roma',
  country: 'IT',
  address1: 'Via Roma 1',
  zip: '12345',
  city: 'Rome',
  source: null,
  phone: '',
  latitude: 42.137833,
  longitude: 12.380085,
  primary_locale: 'en',
  address2: null,
  created_at: '2017-04-26T03:47:03-04:00',
  updated_at: '2020-12-13T01:59:49-05:00',
  country_code: 'IT',
  country_name: 'Italy',
  currency: 'EUR',
  customer_email: 'al.bino@rocketmail.com',
  timezone: '(GMT-05:00) Eastern Time (US & Canada)',
  iana_timezone: 'America/New_York',
  shop_owner: 'Al Bino',
  money_format: '€{{amount}}',
  money_with_currency_format: '€{{amount}} EUR',
  weight_unit: 'kg',
  province_code: 'RM',
  taxes_included: true,
  auto_configure_tax_inclusivity: null,
  tax_shipping: null,
  county_taxes: true,
  plan_display_name: 'Developer Preview',
  plan_name: 'partner_test',
  has_discounts: false,
  has_gift_cards: false,
  myshopify_domain: 'quuz.myshopify.com',
  google_apps_domain: null,
  google_apps_login_enabled: null,
  money_in_emails_format: '€{{amount}}',
  money_with_currency_in_emails_format: '€{{amount}} EUR',
  eligible_for_payments: true,
  requires_extra_payments_agreement: false,
  password_enabled: true,
  has_storefront: true,
  eligible_for_card_reader_giveaway: false,
  finances: true,
  primary_location_id: 42043015,
  cookie_consent_level: 'implicit',
  visitor_tracking_consent_preference: 'allow_all',
  force_ssl: true,
  checkout_api_supported: false,
  multi_location_enabled: true,
  setup_required: false,
  pre_launch_enabled: false,
  enabled_presentment_currencies: [ 'EUR' ]
}

what version of shopify-api-node and Node.js are you using?

axmachina commented 3 years ago

@lpinca you are quite correct, thank you.

I'm running same versions.

Narrowed down to mailgun-js https://github.com/mailgun/mailgun-js-boland/issues/265#issuecomment-743980371