Shopify Node GraphQL App Auth's Successfully But Returns Redirect Error on Install

Highlighted
Shopify Partner
1 0 0

developing a node GraphQL app, following the docs, and going through final tests on a development store. until very recently (1-2 weeks ago), the app authenticated successfully. now I'm seeing different behavior.

 

when I install the app on a dev store:

 

1. app redirects to my auth page with Shopify hmac code in url param

2. then app redirects to an error page

 

Screen Shot 2020-01-22 at 12.50.36 PM.png

 

however, when I go to look at installed apps on the store, I see the app installed successfully on the test store and I can access the app. BUT, if I uninstall the app, I can't reinstall it a second time. it seems like this is either a dependency, API versioning, or a session/cookie issue, but I'm having trouble debugging or narrowing it down further. any recommendations or potential issues you see? thanks

 

server.js

 

require('isomorphic-fetch');
const Koa = require('koa');
const bodyParser = require('koa-body-parser');
const path = require('path');
const cors = require('@koa/cors');
const next = require('next');
const Router = require('koa-router');

const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
const dotenv = require('dotenv');
const { verifyRequest } = require('@shopify/koa-shopify-auth');
const session = require('koa-session');

dotenv.config();
const { default: graphQLProxy } = require('@shopify/koa-shopify-graphql-proxy');
const { ApiVersion } = require('@shopify/koa-shopify-graphql-proxy');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const {
  SHOPIFY_API_SECRET_KEY,
  SHOPIFY_API_KEY
} = process.env;

app.prepare().then(() => {
  const server = new Koa();
  const router = new Router();

  server.use(session(server));
  server.keys = [SHOPIFY_API_SECRET_KEY];

  server.use(cors());

  server.use(
    createShopifyAuth({
      apiKey: SHOPIFY_API_KEY,
      secret: SHOPIFY_API_SECRET_KEY,
      scopes: [
       */ scopes */
      ],
      accessMode: '',
      async afterAuth(ctx) {
        const { shop, accessToken } = ctx.session;

        ctx.cookies.set('shopOrigin', shop, { httpOnly: false });
        ctx.cookies.set('accessToken', accessToken, { httpOnly: false });
        console.log('====>authentication successed');
        ctx.redirect('/');
      }
    })
  );

  server.use(graphQLProxy({ version: ApiVersion.Unstable }));

  router.get('/api/v1/themes', verifyRequest(), async ctx => {
    try {
      const results = await fetch(
        `https://${ctx.cookies.get(
          'shopOrigin'
        )}/admin/api/2019-10/themes.json`,
        {
          headers: {
            'X-Shopify-Access-Token': ctx.cookies.get('accessToken')
          }
        }
      )
        .then(response => response.json())
        .then(json => {
          return json;
        });
      ctx.body = {
        status: 'success',
        data: results
      };
    } catch (err) {
      console.log('===================> error', err);
    }
  });

  router.put('/api/v1/themes/:themeID', verifyRequest(), async ctx => {
    const obj = JSON.parse(ctx.request.body);

    try {
      const results = await fetch(
        `https://${ctx.cookies.get('shopOrigin')}/admin/api/2019-10/themes/${
          ctx.params.themeID
        }/assets.json`,
        {
          method: 'PUT',
          headers: {
            'X-Shopify-Access-Token': ctx.cookies.get('accessToken'),
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            asset: {
              key: 'assets/shipping_method_recommend.css',
              value: `.shipping-method { display: ${obj.show}; }`
            }
          })
        }
      )
        .then(response => response.json())
        .then(json => {
          return json;
        });
      ctx.body = {
        status: 'success',
        data: results
      };
    } catch (err) {
      console.log('===================> error', err);
    }
  });

  router.get('*', verifyRequest(), async ctx => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
  });

  server.use(router.allowedMethods());
  server.use(bodyParser());

  server.use(router.routes());
});

 

app logs:

 

 
Jan 22 09:59:41: at=info method=GET path="/admin/auth/login" host=app.com request_id=d6c472bf-390c-4ffc-9906-f845d011d3b9 fwd="158.106.192.162" dyno=web.1 connect=1ms service=11ms status=404 bytes=48030 protocol=https

Jan 22 09:59:42: at=info method=GET path="/api/v1/themes" host=app.com request_id=ba891cdd-65b4-4cbf-bccb-9414a138ccb4 fwd="158.106.192.162" dyno=web.1 connect=0ms service=115ms status=200 bytes=366 protocol=https

Jan 22 09:59:42: at=info method=POST path="/graphql" host=app.com request_id=b0865c03-41fa-433e-9088-326010e098c0 fwd="158.106.192.162" dyno=web.1 connect=0ms service=120ms status=301 bytes=3168 protocol=https 

 

app dependencies:

 

"@koa/cors": "^3.0.0",
"@shopify/app-bridge-react": "^1.11.0",
"@shopify/koa-shopify-auth": "^3.1.53",
"@shopify/koa-shopify-graphql-proxy": "^3.1.1",
"@shopify/koa-shopify-webhooks": "^2.2.2",
"@shopify/polaris": "^3.13.0",
"@shopify/polaris-icons": "^3.7.0",
"@zeit/next-css": "^1.0.1",
"apollo-boost": "^0.4.1",
"apollo-client": "^2.6.4",
"dotenv": "^8.0.0",
"graphql": "^14.3.0",
"graphql-tag": "^2.10.1",
"isomorphic-fetch": "^2.2.1",
"js-cookie": "^2.2.0",
"koa": "^2.7.0",
"koa-body-parser": "^1.1.2",
"koa-router": "^7.4.0",
"koa-session": "^5.12.3",
"moment": "^2.24.0",
"next": "^8.1.0",
"next-offline": "^3.3.7",
"next-redux-wrapper": "^3.0.0-alpha.2",
"next-routes": "^1.4.2",
"react": "^16.8.6",
"react-apollo": "^2.5.5",
"react-dom": "^16.8.6",
"react-redux": "^7.0.2",
"react-table": "^6.10.3",
"redux": "^3.7.2",
"store-js": "^2.0.4",
"styled-components": "^4.2.0",
"url-loader": "^1.1.2",
"webpack": "^4.31.0"

 

0 Likes
Highlighted
Shopify Staff
Shopify Staff
39 7 8

I can't see any issues with your code. How are you installing your app? Is it through the admin? Have you tried clearing your cookies and trying again?

0 Likes