Shopify app authorization gets stuck in an infinite redirect

Hi, I have a Shopify Remix app that is not embedded in the Shopify admin. I have successfully tested it locally and even dockerized it to run locally without issues.

Then, I deployed it to production on my virtual machine, which has Nginx and Docker Compose. Requests to my Shopify app go through the /shopify route on my server and are routed to my Shopify app.

I believe I have configured everything correctly, but when I try to install the app on my development store, I get stuck in a loop. The application does not authenticate properly and, as a result, fails to store the session.

After being stuck in the loop for a while , Shopify returns the error:
“The application cannot be loaded. It may be misconfigured. Please contact the application author.”

Please help!



image

I think this topic has the same problems, and doesn’t have the solution also: ruby on rails - shopify app authorization gets stuck in an infinite redirect - Stack Overflow

Hey @Tri_t_Minh :waving_hand: - I can’t say for certain what’s triggering the issue, but there are few common reasons this pops up.

If you haven’t checked already, can you see if your app’s shopify.app.toml matches the .env file of your hosted server (if this is how you’ve configured the set up on that end)? It looks like that may have fixed the same/a similar issue for this dev here: Non Embedded App throwing "The application cannot be loaded, it may be misconfigured" Error in Production · Issue #671 · Shopify/shopify-app-template-remix · GitHub

If you’re still seeing the issue pop up after that though, could you look at that apps?oauth_error=…` event and see if you’re able to grab a request ID from the response headers in your browser’s network tab within dev tools? I can share that with our developers on my end and we can take a closer look at the logs of the above doesn’t help resolve the issue.

I checked my env file and tried to install again. Still no work. This is the request ID:
348031a3-8348-4e44-a1f5-846eb32525ab-1743610583

Thanks for trying that @Tri_t_Minh and for sharing that request ID - I was able to pull your example in our logs here - this does look odd from what I can tell, especially if you confirmed the .toml config and your environment matched.

I’ll reach out to our app auth component developers for you and loop back with you here when I have some more info to share. :slight_smile:

1 Like

@Tri_t_Minh :waving_hand: - just following up here - I was able to work with our developers on this for you. From what we could tell. it does seem like your app is trying to go through the OAuth process to get a new token.

We can’t say for sure, but our thinking is the app doesn’t appear to fully perform the exchange of the authorization code for the token (or may not be properly storing the token). Could you check to see if the token is being stored correctly on your end - our hunch is that this might be what’s causing the issue here, especially if things are working when you run the process locally.

Hi @Tri_t_Minh - just wanted to check if you’re still experiencing this issue?

Hi, sorry for the late reply. Thank you all for your help. I tried to fix the problem without changing the old flow, but it seemed hopeless. So instead of using authenticate.admin in the auth.callback.jsx file, I manually requested the access token by following this document.

Here’s my current flow:

  1. Receive the /auth/callback request
  2. Validate that the nonce matches the state, and verify the HMAC and shop
  3. Exchange the authorization code for an access token
  4. Set two cookies in the response header: shopify_app_session and shopify_app_session.sig
  5. Return res.redirect with shop and host params

All the steps above follow the docs, except for step 4. It took me quite some time to realize that I needed to set those two cookies in the response header to complete the OAuth flow. I wasn’t sure how Shopify originally created shopify_app_session.sig, and had to do some guesswork to figure it out.

I think the documentation doesn’t mention that step because it assumes the reader is implementing the OAuth flow manually from start to finish—whereas in my case, I only implemented the /callback part manually.

Glad you figured this out - have noted your feedback for improving our docs!