Bad request (400) while requesting access token

Solved
Highlighted
Shopify Partner
8 2 2

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.

0 Likes
Highlighted
Shopify Partner
8 2 2

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: 

Oauth error invalid_request: The authorization code was not found or was already used
0 Likes
Highlighted
Shopify Partner
8 2 2

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.

1 Like
Highlighted
Tourist
18 0 1

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 

0 Likes