How to verify requests from Shopify public app to custom api endpoints

Solved
orlyohreally
New Member
2 0 0

I am developing a Shopify embedded public app with a form on the main page. I need to submit this form to my app API endpoint and this endpoint should be available only to valid stores that have installed my app. The auth process was developed with @shopify/koa-shopify-auth and I used their example app code:

import 'isomorphic-fetch';

import Koa from 'koa';
import session from 'koa-session';
import shopifyAuth, {verifyRequest} from '@shopify/koa-shopify-auth';

const {SHOPIFY_API_KEY, SHOPIFY_SECRET} = process.env;

const app = new Koa();
app.keys = [SHOPIFY_SECRET];

app
// sets up secure session data on each request
.use(session({secure: true, sameSite: 'none'}, app))

// sets up shopify auth
.use(
shopifyAuth({
apiKey: SHOPIFY_API_KEY,
secret: SHOPIFY_SECRET,
scopes: ['write_orders, write_products'],
afterAuth(ctx) {
const {shop, accessToken} = ctx.session;

console.log('We did it!', accessToken);

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

// everything after this point will require authentication
.use(verifyRequest())

// application code
.use(ctx => {
ctx.body = '';
});

I know that to verify requests to check that they came from Shopify it is possible to use hmac that they append to app URL. To make a request with form data I use axios, so should I manually add query parameters (like hmac and etc.) to request URL, or that is not a good practise.

Also, the sample app code uses a middleware verifyRequest. I could not fully understand could it be used for custom API endpoints as well or not. Any help will be appreciated because I have spent lots of time on figuring it all out, but still completely don't feel sure.

Accepted Solution (1)

Accepted Solutions
AndyPicamaze
Explorer
41 1 14

This is an accepted solution.

Hi

Looking at your code, if you process the post request in the last .use statement it should be protected since it is below the verifyRequest() method.

Another way to do this is via router. You can use the verifyRequest() method for POST requests:

const { default: shopifyAuth, verifyRequest } = require('@shopify/koa-shopify-auth');
...
const router = new Router();
...
router.post('/yourformurl', verifyRequest(), async (ctx) => ...)); // This will protect your url from unauthorised access

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

 Let me know if that helps.

https://apps.shopify.com/picamaze
Animated watermarks for product images and ads

View solution in original post

Replies 4 (4)
AndyPicamaze
Explorer
41 1 14

This is an accepted solution.

Hi

Looking at your code, if you process the post request in the last .use statement it should be protected since it is below the verifyRequest() method.

Another way to do this is via router. You can use the verifyRequest() method for POST requests:

const { default: shopifyAuth, verifyRequest } = require('@shopify/koa-shopify-auth');
...
const router = new Router();
...
router.post('/yourformurl', verifyRequest(), async (ctx) => ...)); // This will protect your url from unauthorised access

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

 Let me know if that helps.

https://apps.shopify.com/picamaze
Animated watermarks for product images and ads

View solution in original post

orlyohreally
New Member
2 0 0

@AndyPicamaze, I am using a router. So if I add to router endpoint verifyRequest middleware then I don't need to check that session.shop and session.accessToken are matching, right? So all I need to do is to check that this shop has installed the app already?

AndyPicamaze
Explorer
41 1 14

Hi,

So if I add to router endpoint verifyRequest middleware then I don't need to check that session.shop and session.accessToken are matching, right?

Yes, If you look at the code of @Koa-auth-shopify you'll see that they are checking the access token for you so you don't need to worry about it.

So all I need to do is to check that this shop has installed the app already? 

If you use shopifyAuth method you don't need to check anything manually. This method does this for you. If you don't have the token then it redirects you to shopify's oath to get it.

shopifyAuth({...

 

https://apps.shopify.com/picamaze
Animated watermarks for product images and ads
gov
New Member
2 0 0

Hey Andy,

Thanks for your response. I'm able to verify the request correctly using your example. However, how does one know who/which shop is making the request? verifyRequest does all the under the hood but doesn't seem to to expose the accessToken nor the shop domain. It seems I will have to do that manually and replicate the behavior of verifyRequest which kind of makes verifyRequest useless. 

How are you identifying who is making the request? 

Thanks!

Govind