Skip to content

Offline access token expires after ~3600s due to hardcoded expiring=1 #12

Description

@aliaksei-safronenka

Description

ShopifyApp::exchangeUsingTokenExchange() always sends 'expiring' => 1 in the Token Exchange request body, regardless of the requested $accessMode. This causes offline tokens to expire after ~3600 seconds instead of being permanent.

Affected file

src/Internal/Exchange/TokenExchange.php

The request body is built with a hardcoded 'expiring' => 1 at the end, which applies to all access modes including offline.

Expected behavior

The Shopify Token Exchange API treats the expiring parameter differently depending on its value. When expiring=0 is sent (or the parameter is omitted), Shopify returns a non-expiring offline token with no expires_in and no refresh_token in the response. When expiring=1 is sent, Shopify returns a short-lived token with a ~3600s TTL and includes a refresh_token for later renewal.

When $accessMode is offline, the library should send expiring=0 to receive a permanent token. Sending expiring=1 silently opts the caller into short-lived tokens, which is only appropriate for online mode.

Actual behavior

All offline token exchange requests receive a token with ~3600s TTL. Any process that stores and reuses the offline token starts failing with 401 Unauthorized approximately one hour after the token was issued.

Links

https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens/token-exchange
https://shopify.dev/changelog/offline-access-tokens-now-support-expiry-and-refresh

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions