Skip to content

Instantly share code, notes, and snippets.

@Jropp
Last active September 18, 2021 20:12
Show Gist options
  • Save Jropp/6f53e01402788598c26beaeabaa3e494 to your computer and use it in GitHub Desktop.
Save Jropp/6f53e01402788598c26beaeabaa3e494 to your computer and use it in GitHub Desktop.

What Is Working

Redirect from Shopify to my Express App

When I click the button to start the install of my sales channel on my test store it appropriately hits my express app /install endpoint:

app.get('/install', (req, res) => {
  const {shop} = req.query;
  const api_key = APP_API_KEY;
  const nonce = uuidv4();
  const scopes = `read_orders,write_orders`;

  const url = `https://${shop}/admin/oauth/authorize?client_id=${api_key}&scope=${scopes}&redirect_uri=https://staging.mainstreet.market/shopify/authorize&state=${nonce}`;

  res.redirect(url);
});

Shopify permissions prompt

The redirect to https://${shop}/admin/oauth/authorize?client_id=${api_key}&scope=${scopes}&redirect_uri=https://staging.mainstreet.market/shopify/authorize&state=${nonce}; that happens in my /install endpoint works appropriately and I am prompted to allow access to the scopes requested in the scope parameter in the URL

Redirect to my Express App

After permissions are set and approved, it is appropriately redirecting back to my Express app's /authorize endpoint which makes a fetch to get the token:

app.get('/authorize', async (req, res) => {
  try {
    const installRequest = await getShopifyInstallRequest(req.query.state, knex);

    if (installRequest) {
      const {shop, nonce} = installRequest;
      const headers = {'Access-Control-Allow-Headers': '*', 'content-type': 'application/json'}

      const token = await fetch(`https://${shop}/admin/oauth/access_token`, {headers, method: 'POST', body: JSON.stringify({
        client_id: APP_API_KEY,
        client_secret: APP_API_SECRET_KEY,
        code: nonce
      })});

      res.send(token);
    } else {
      res.status(401);
      res.send('No install request found');
    }
  } catch (error) {
    console.error(error);
  }
});

The Problem

The response here is what confuses me. I've tried a number of formats but can't seem to get a 200 on any of them.

Response {
   size: 0,
   timeout: 0,
   [Symbol(Body internals)]: {
     body: PassThrough {
       _readableState: [ReadableState],
       readable: true,
       _events: [Object: null prototype],
       _eventsCount: 5,
       _maxListeners: undefined,
       _writableState: [WritableState],
       writable: true,
       allowHalfOpen: true,
       _transformState: [Object],
       [Symbol(kCapture)]: false
     },
     disturbed: false,
     error: null
   },
   [Symbol(Response internals)]: {
     url: 'https://umm-sales-channel-test.myshopify.com/admin/oauth/access_token',
     status: 400,
     statusText: 'Bad Request',
     headers: Headers { [Symbol(map)]: [Object: null prototype] },
     counter: 0
   }
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment