Hi,
I am trying to get offline access token in my node.js application. Basically I got hmac and code after auth and trying to exchange it for a permanent access_token:
//await validShopifyRequest(secret, ctx.query); //temporarily commented out console.log('Authentic hmac!'); const accessTokenRequest = JSON.stringify({ 'client_id': apiKey, 'client_secret': secret, 'code': ctx.query.code }); console.log(`==request to get access token: ${accessTokenRequest}`); const getResponse = await fetch(`https://${shop}/admin/oauth/access_token`, { method: "POST" , headers: { 'Content-Type': 'application/json', } , body: JSON.stringify({ 'client_id': apiKey, 'client_secret': secret, 'code': ctx.query.code }) }); console.log(`=====data after get token=====`, getResponse);
This code generates these logs
Authentic hmac! ==request to get access token: {"client_id":"*******************","client_secret":"*******************","code":"7665714288c4b975466bab2fbe05d028"} =====data after get token===== Body { url: 'https://avet-dvlp.myshopify.com/admin/oauth/access_token', status: 400, statusText: 'Bad Request', ...
Any idea what could be wrong here?
Thanks.
Solved! Go to the solution
More details:
I simplified the code:
app.prepare().then(() => { const server = new Koa(); 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', 'read_orders', 'write_orders'], async afterAuth(ctx) { const { shop, accessToken } = ctx.session; ctx.cookies.set('shopOrigin', shop, { httpOnly: false }); //get offline access token console.log(`=========query parameters:`, ctx.query); const accessTokenRequest = JSON.stringify({ 'client_id': SHOPIFY_API_KEY, 'client_secret': SHOPIFY_API_SECRET_KEY, 'code': ctx.query.code }); console.log(`==request to get access token: ${accessTokenRequest}`);
grabbed request from the log and tried to send it from Insomnia. Response is also 400 (Bad request) but I also got this error message:
This is an accepted solution.
Well, apparently you don't need to exchange the code to access token manually. koa-shopify-auth allows to request an offline access token as specified here: https://www.npmjs.com/package/@shopify/koa-shopify-auth
So final code look like this:
app.prepare().then(() => { const server = new Koa(); 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', 'read_orders', 'write_orders'], accessMode: 'offline', async afterAuth(ctx) { const { shop, accessToken } = ctx.session; ctx.cookies.set('shopOrigin', shop, { httpOnly: false }); console.log(`=========access token (offline):`, accessToken); ...
this access token can be used to execute GQL queries.
Thank you @avet I was under the impression that it would be needed to create another authentication flow, and this is actually very simple, I could not find this solution myself (the simple accessMode: "offline",) so thank you for coming back to this thread and sharing the solution.
Note for others, if you are having this same issue and you have created your app based on the Build a Shopify App with Node and React, all you have to do is add accessMode: "offline" to your auth call:
server.use( createShopifyAuth({ apiKey: SHOPIFY_API_KEY, secret: SHOPIFY_API_SECRET_KEY, scopes: appConfig.shopifyScopes, accessMode: "offline", //<-------- add this
I know that the reply above this one already have this, but I overlooked it when I first read this post and ended up only finding this out in the npm for koa-shopify-auth
User | Count |
---|---|
12 | |
12 | |
10 | |
7 | |
6 |