Bad request (400) while requesting access token

Solved
Highlighted
Tourist
6 2 0

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
Tourist
6 2 0

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

Success.

Tourist
6 2 0

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.

0 Likes