Getting session token in axios intercept

Malthe
Tourist
7 0 1

Hey everyone!

I'm building an embedded app with Next.js as my frontend, and Next.js api routes as my serverless backend. 

I have set my backend up to accept and verify JWT session tokens, which seems to work fine. However my problem lies in my way of sending authenticated requests from my frontend to my backend.

I have set up the app  bridge and was using getSessionToken(app) function to  get the current JWT, but since that is only valid for one minute I have to request a the newest one on every request.

Since I'm using axios for requests to my backend, I followed this tutorial: https://shopify.dev/tutorials/use-session-tokens-with-axios. But after implementing that, I'm getting the following errors on my frontend: TypeError: Cannot read property 'subscribe' of undefined.

This is the exact code for my axios intercept:

import axios from 'axios';
import { getSessionToken } from "@shopify/app-bridge-utils";


const instance = axios.create({
    baseURL: process.env.DEV_TUNNEL_URL,
    headers: {
        post: { // Can be common or any other method
            'Content-Type': 'application/json'
        },
        patch: {
            'Content-Type': 'application/json'
        },
        delete: {
            'Content-Type': 'application/json'
        },
    }
});

// Intercept all requests on this axios instance
instance.interceptors.request.use((config) => {
    console.log(window.app)
    return getSessionToken(window.app) // requires an App Bridge instance
        .then((token) => {
            // Append your request headers with an authenticated token
            config.headers["Authorization"] = `Bearer ${token}`;
            return config;
        });
});

 

I also noticed that window.app is undefined. How can I get the correct app reference in a react app using axios intercept?

 

I hope you can help me shin some light on this (-:

Thanks very much in advance!

Mircea_Piturca
Shopify Partner
1473 42 300

Hey there,

Yeah, I've been playing with this all day today. Got the same error, not defined.

I've ended up creating an app by passing the API_KEY and shopOrigin on _app.js

  const app = createApp({
    apiKey: API_KEY,
    shopOrigin: shopOrigin
  });

 

I have both of those vars defined in _app.js. Looks like a hack but it's the only way I got it to work.

The docs are a bit confusing to me. 

Finally—Add variant descriptions to your products
JoshHighland
Shopify Expert
63 1 21
import axios from 'axios';
import { useAppBridge } from '@shopify/app-bridge-react';
import { getSessionToken } from '@shopify/app-bridge-utils';

const app = useAppBridge();

 

You can use useAppBridge to gain access to app also.

Malthe
Tourist
7 0 1

Thank you for your answer! Will this also work outside of a react component?

 

0 Likes
StefanoDiLegami
Tourist
4 1 2

Hey @Malthe, did u get this work now?

0 Likes
Malthe
Tourist
7 0 1

Hey. No not exactly I'm afraid. 

I ended up using the authenticatedFetch function that app bridge provides. But I would prefer to use axios to be honest. Let me know if you figure it out (-:

0 Likes
StefanoDiLegami
Tourist
4 1 2

I could get it to work in that way:

File: _app.js

 

function MyProvider(props) {
  const app = useAppBridge();

  // Create axios instance for authenticated request
  const authAxios = axios.create();
  // intercept all requests on this axios instance
  authAxios.interceptors.request.use(function (config) {
    return getSessionToken(app)
      .then((token) => {
        // append your request headers with an authenticated token
        config.headers["Authorization"] = `Bearer ${token}`;
        return config;
      });
  });

  const Component = props.Component;

  return (
      <Component {...props}  authAxios={authAxios} />
  );
}

 

Im passing authAxios down to Component  and use axios in that way, when i need authenticated requests. 

 

  authAxios.get('/api/products')
      .then(result => console.log(result))
      .catch(error => console.log(error))

 

Hope it helps.

 

Malthe
Tourist
7 0 1

Awesome! I will give that a try, thank you.

0 Likes
Bradyango
New Member
1 0 0

Evening Sir!

Any luck on this? 

We are facing a very similar issue. 

0 Likes
scole954387
Excursionist
13 0 3

I'm very new to react/node.  I tried to use what you provided with the shopify CLI boilerplate app and it doesn't seem to work.  Can you tell me what I've done wrong?  Thanks!

 

function MyProvider(props) {
  const app = useAppBridge();

  // Create axios instance for authenticated request
  const authAxios = axios.create();
  // intercept all requests on this axios instance
  authAxios.interceptors.request.use(function (config) {
    return getSessionToken(app)
      .then((token) => {
        // append your request headers with an authenticated token
        config.headers["Authorization"] = `Bearer ${token}`;
        return config;
      });
  });


  const client = new ApolloClient({
    fetch: authenticatedFetch(app),
    fetchOptions: {
      credentials: "include",
    },
  });

  const Component = props.Component;

  return (
    <ApolloProvider client={client}>
      <Component {...props} authAxios={authAxios} />
    </ApolloProvider>
  );
}