Web

Shopify App Reinstall OAuth Access Token Fix

Handle Shopify app reinstallation from Uninstalled tab without OAuth code. Detect 401 errors, trigger re-OAuth for access token regeneration, and use APP_UNINSTALLED webhook for clean sessions.

1 answer 1 view

How should I handle OAuth access token regeneration when a custom Shopify app is uninstalled and then reinstalled from Shopify Admin → Apps > Uninstalled?

Context:

  • The app uses the standard OAuth flow: the merchant enters the shop domain in my app, is redirected to Shopify for approval, then Shopify redirects back to my app with a code parameter which I exchange for an access token.
  • When the app is reinstalled from Apps > Uninstalled, Shopify does not redirect to my app and no code parameter is provided, so I cannot regenerate an access token.

Questions:

  1. What is the recommended way to regenerate access tokens when an app is reinstalled from the Uninstalled tab? Are there specific webhooks (e.g., app/installed) or flows I should rely on?
  2. Alternatively, is it possible to prevent an app from being reinstallable from the Uninstalled list and require installation only via the app URL (like the Shopify GraphiQL App)? If so, how?

Handling Shopify app reinstallation from the Uninstalled tab skips the standard OAuth flow, so no code parameter arrives for OAuth access token regeneration. The best fix? Catch 401/403 errors from API calls with your old token, then kick off a fresh OAuth process to grab a new access token. Pair this with a solid APP_UNINSTALLED webhook to wipe old sessions cleanly—it’s the Shopify-recommended way to avoid stale data headaches.


Contents


Understanding the Shopify App Reinstallation Problem

Ever built a custom Shopify app that works great on first install? Merchant punches in their shop domain, OAuth kicks in, you snag that sweet access token, and everything hums. But then they uninstall from Shopify Admin → Apps, hit the Uninstalled tab later, and click reinstall. Boom—no redirect to your app URL. No code parameter. Your old token? Probably toast.

This trips up tons of devs. Shopify’s design assumes you’ll handle it gracefully. From community threads, it’s clear: reinstalls from Uninstalled bypass your app’s OAuth callback entirely. You’re left assuming the prior token still works—until it doesn’t, spitting 401 Unauthorized errors mid-API call.

Why? Uninstall triggers cleanup like deleting webhooks and script tags, per official docs. But reinstall doesn’t always notify your app. No app/installed webhook exists (it’s APP_UNINSTALLED for the opposite). Result? Stale sessions linger if your webhook flakes.

Short version: Don’t rely on reinstall triggering OAuth. Build defenses.


Why the OAuth Flow Breaks on Reinstall

Your standard flow—shop domain entry → Shopify approval → callback with code → exchange for access token—nails fresh installs. Reinstalls from Uninstalled? Shopify just reactivates the app listing without pinging you.

GitHub issues on Shopify’s CLI template nail this: If your APP_UNINSTALLED webhook deletes shop data properly, reinstall shows “Nothing Found” because no session exists. Catch-22. And Stack Overflow devs report: Even quick uninstall-reinstall sequences leave old tokens invalid after a delay.

No magic app/reinstalled event. Shopify’s installation docs push “Shopify-managed installations,” but that’s for public apps updating scopes without full OAuth. Custom apps like yours? Stick to manual handling.

Here’s the rub: Webhooks can be unreliable in dev mode or with network hiccups, as seen in multiple forum posts.


Detect Invalid Tokens and Trigger Re-OAuth

Smartest move? Don’t wait for perfect webhooks. Test your access token proactively.

The go-to hack from Shopify’s shopify_app gem issues: On any API hit (say, fetching shop details), wrap it in a try-catch. 401 or 403? Old token’s dead—redirect to OAuth immediately.

javascript
// Pseudo-code example
async function makeApiCall(token, shop) {
 try {
 const response = await fetch(`https://${shop}/admin/api/2023-10/shop.json`, {
 headers: { 'X-Shopify-Access-Token': token }
 });
 if (!response.ok) {
 if (response.status === 401 || response.status === 403) {
 // Token invalid – trigger re-OAuth
 redirectToOAuth(shop);
 }
 throw new Error('API error');
 }
 return response.json();
 } catch (error) {
 console.error('API failed:', error);
 }
}

This catches reinstalls on-the-fly. Users see a quick “Re-authorize” prompt. No data loss, seamless.

Another Stack Overflow thread echoes: Dummy API call first, invalidate on 403, refresh token.

Pro tip: Do this on app load or key pages. You’ll regenerate OAuth access tokens exactly when needed.


Set Up the APP_UNINSTALLED Webhook Properly

Webhooks are your cleanup crew. Register APP_UNINSTALLED during install—Shopify fires it on uninstall.

From Node.js examples:

javascript
// Register on install
await Shopify.Webhooks.Registry.register({
 shop,
 accessToken,
 path: '/api/webhooks',
 topic: 'APP_UNINSTALLED',
 webhookHandler: async (topic, shop, body) => {
 await deleteSession(shop); // Wipe DB entry
 }
});

Handle the POST:

javascript
app.post('/api/webhooks', async (req, res) => {
 // Verify HMAC, etc.
 await deleteShopData(req.body.shop_domain);
 res.status(200).send('OK');
});

Issues? Dev apps sometimes skip delivery (forum gripe). Use ngrok stably, verify HMAC strictly. On success, it nukes your session—reinstall then forces fresh OAuth naturally.

PHP folks, check this access token exchange for the callback handler.


Regenerate Access Tokens Step-by-Step

  1. Detect failure: 401 on API.
  2. Redirect: https://${shop}/admin/oauth/authorize?client_id=${API_KEY}&scope=${SCOPES}&redirect_uri=${YOUR_URL}
  3. Callback: Grab code, POST to https://${shop}/admin/oauth/access_token with client_id, client_secret, code.
  4. Store new token: Update DB, resume.

Full PHP snippet from SO:

php
function getAccessToken($shop, $apiKey, $secret, $code) {
 $query = [
 'client_id' => $apiKey,
 'client_secret' => $secret,
 'code' => $code
 ];
 $access_token_url = "https://{$shop}/admin/oauth/access_token";
 $curl = curl_init();
 curl_setopt_array($curl, [
 CURLOPT_RETURNTRANSFER => true,
 CURLOPT_URL => $access_token_url,
 CURLOPT_POSTFIELDS => http_build_query($query)
 ]);
 $response = json_decode(curl_exec($curl), true);
 curl_close($curl);
 return $response['access_token'];
}

Test rigorously. Works for offline tokens too.


Can You Block Reinstalls from Uninstalled Tab?

Short answer: Nope, not directly. Shopify controls the Uninstalled list—your app lives there post-uninstall.

GraphiQL app? Special case, Shopify-owned, skips public listing quirks. Custom apps can’t mimic that.

Workarounds? Force URL-only installs by ditching app store submission, but reinstalls still hit Uninstalled. Official install guide confirms: Merchants use that tab freely.

Best bet: Embrace the 401 → OAuth flow. It’s robust, user-friendly. No fights with Shopify’s UI.


Best Practices for Token Management

  • Always verify tokens on critical paths.
  • Scope minimally—reinstalls inherit prior scopes.
  • Log webhook deliveries—debug flakes.
  • Offline tokens: They refresh via OAuth, per recent SO fix.
  • Multi-shop: Key sessions by shop domain.
  • Test uninstall-reinstall loops in dev stores.

This setup scales. Handles edge cases like instant re-installs where webhooks lag.


Sources

  1. Stack Overflow: Generate new Shopify access token after reinstall
  2. Shopify Community: OAuth issue on Uninstalled tab reinstall
  3. GitHub: shopify_app offline token refresh on reinstall
  4. Stack Overflow: Handle uninstall then instant reinstall
  5. Shopify Docs: Uninstall app API request
  6. Shopify Docs: App installation
  7. Stack Overflow: APP_UNINSTALLED webhook Node.js
  8. GitHub: shopify-app-template-node reinstall issue

Conclusion

Master Shopify app reinstallation by leaning on 401 detection for OAuth access token regeneration—it’s reliable when webhooks waver. Clean up via APP_UNINSTALLED, force fresh auth on failure, and skip dreams of blocking Uninstalled tab access. Your app stays bulletproof, merchants happy. Implement today; those loops won’t haunt you anymore.

Authors
Verified by moderation
Moderation
Shopify App Reinstall OAuth Access Token Fix