Embedded app: Saving and identifying shops from external Rest API

Solved
Highlighted
Shopify Partner
5 1 4

Hi there,

 

I am trying to implemented something similar in terms of identifying shops with an offline token. How can I store and identify a store when using an external custom API. I have followed the React + Node.js tutorial. 

 

require('isomorphic-fetch');
const Koa = require('koa');
const Router = require('koa-router');
const next = require('next');
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(
        createShopifyAuth({
            apiKey: SHOPIFY_API_KEY,
            secret: SHOPIFY_API_SECRET_KEY,
            scopes: ['read_products', 'write_products'],
accessMode: "Offline", async afterAuth(ctx) { const { shop, accessToken } = ctx.session; ctx.cookies.set('shopOrigin', shop, { httpOnly: false }) ctx.cookies.set('accessToken', accessToken); ctx.redirect('/'); }, }), ); server.use(graphQLProxy({ version: ApiVersion.April19 })) server.use(verifyRequest()); server.use(async (ctx) => { await handle(ctx.req, ctx.res); ctx.respond = false; ctx.res.statusCode = 200; return }); server.listen(port, () => { console.log(`> Ready on http://localhost:${port}`); }); });

 

 

I have built an external Express.js Rest API that handles most of the logic and interacts with the database for the app. My issues is are:

  • In order for me to save the shop and the token to the database through the API. How can I make a POST request to the external API to save the shop.
  • Also at what stage do I call the the external Express API to retrieve and verify the shop. And how can I reuse the the access token to make queries to shopify with GraphQL.
  • My other question is, what is the purpose if verifyRequest in the Shopify-koa-auth and how does it work?

I have been going through an number of other questions on the community and I think this one, I think was the closest to what I'am trying to achieve.  I am  fairly new to the shopify environment and the frameworks being used. I am not sure if i am thinking about this the right way. Please if you may assist me with this.  Any help is greatly appreciated. Thank you

1 Like
Highlighted
Shopify Partner
5 1 4

This is an accepted solution.

I came up with something that works for me. I have put it here in case someone is having a similar problem. After a number of attempts, I ended up making a request to my API just after the shopOrigin and accessToken are generated in afterAuth.

 

server.use(
    ...
      async afterAuth(ctx) {
        const { shop, accessToken } = ctx.session;
        ctx.cookies.set("shopOrigin", shop, {
          httpOnly: false,
          secure: true,
          sameSite: 'none'
        });

        const savedShop = await saveAccessTokenForShop(shop, accessToken);
        if (savedShop) {
          console.log('Good');
          let options = {
            httpOnly: false,
            secure: true,
            sameSite: 'none'
          }
          // Only call shopify token from database when needed
          ctx.cookies.set('accessToken', savedShop.accessToken, options);            
        } else {
          console.log('Shop not saved');
        } 

        ctx.redirect('/');
      },
    ...
  );

 

This is how my saveAccessTokenForShop() function looks like:

 

const saveAccessTokenForShop = async (shop, accessToken) => {
// logic for saving shop and accesToken through API or directly on database 
  try {
    const requestOptions = {
      method: "POST",
      body: JSON.stringify({
        shop: shop,
        shopify_token: accessToken
      }),
      headers: {
        "Content-type": "application/json; charset=UTF-8"
      }
    }
    // request to Express API
    return await fetch('http://localhost:3001/api/shop/', requestOptions).then(response => response.json());
  } catch (err) {
    return(err)
  }
}

The request to my API handles the logic. If the shop already exists in the database the retrieves the shop data, if not it creates a new entry on the database.

I'm not sure if this is good practice though. I hope this helps.

 

1 Like