Liquid, JavaScript, themes, sales channels
To continue receiving payouts, you need to secure your account by turning on two-step authentication. If two-step authentication is not turned on your payouts will be paused. Learn more
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.
Solved! Go to the solution
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.
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.
@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?
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({...
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
Would you love to unleash the unbridled power of the Google Shopping Channel into your sho...
By Gabe Jan 6, 2023How can you turn a hobby into a career? That’s what Emmanuel did while working as a wa...
By Skye Dec 30, 2022Shipping can be one of the most vital parts to set up and manage your business. Understand...
By Ollie Dec 16, 2022