All Tutorials

Authenticate an embedded app using session tokens

All Tutorials

Authenticate an embedded app using session tokens

Authenticate an embedded app using session tokens

This tutorial describes the requirements, recommendations, and frontend and backend changes associated with setting up session token authentication in your embedded app.

For an introduction to session tokens, refer to Building embedded apps using session tokens.

Requirements

Recommendations

It's easier to enable session token authentication on single-page apps. Without cookies, every new page load needs to be a two-step process. The first step is an unauthenticated load of the frontend JavaScript to instantiate App Bridge. The second step uses the session token to start fetching the merchant data.

If you have a multi-page app, then you might be able to convert it to behave as if it were a single-page app using Turbolinks.

Backend changes

You must make changes to the backend to set up session token authentication in your embedded app.

1. Decode the session tokens for incoming requests

Your app will need to decode session tokens from incoming requests on the backend.

2. Allow unauthenticated requests

Update the route that serves the app so that it allows unauthenticated requests.

If the page server-rendered by this route depends on an authenticated request to the route, remove the protected data from the response and expose it to the frontend using an authenticated API route. For example, your app might be embedding merchant information in its initial HTML response.

Add logic to the unauthenticated route to detect if this is the first time the shop is loading your app.

If your app doesn't have a shop/offline access token for the shop, then the route should respond with a redirect to send the user to the OAuth login flow. This ensures that the app is installed and receives its shop token.

If your app uses user/online access tokens, then you will need to redirect the user a second time to the OAuth flow.

3. Add middleware

Add middleware that detects requests with a session token present and builds a session based on the shop and user information included in the token.

To verify the authenticity of a session token, refer to Verify the signature.

4. Mark shops as uninstalled using the app/uninstalled webhook

To ensure OAuth continues to work with session tokens, your app must mark shop records as uninstalled when a shop uninstalls your app. Your app can receive notifications of uninstalls by subscribing to the app/uninstalled webhook. You should also set up the webhook subscription for any shops that have already installed your app. For example, you could use the webhookSubscriptionCreate endpoint, or create a background job to subscribe to the webhook.

5. Handle changes to access scopes requested by your app

Your app must keep track of the access scopes currently authorized for each shop to determine whether they match the scopes currently requested by your app. If the scopes currently authorized don't match the scopes currently requested by your app, then your app must initiate the OAuth login flow to ask the merchant to authorize the new scopes.

To determine whether currently authorized scopes match currently requested scopes, you can store the current access scopes on your app or query them using the GraphQL Admin API or REST Admin API:

  • GraphQL Admin API: Query the accessScopes field on the AppInstallation object.
  • REST Admin API: Make a request to the GET /admin/oauth/access_scopes.json endpoint on the AccessScope resource.

6. Handle the expiry of online access tokens

Apps that use online access tokens must keep track of whether the token is expired. If the online access token is expired, then the user needs to go through the OAuth login flow to retrieve a new token.

Frontend changes

You must make changes to the frontend to set up session token authentication in your embedded app.

1. Load App Bridge in Skeleton/Loading page

Once your unauthenticated routes serves the initial JavaScript, create an App Bridge instance on the frontend. For more details on setting up App Bridge, you can refer to: Getting started with Shopify App Bridge.

2. Start fetching protected data with session tokens

With the App Bridge instance created, you can now start getting session tokens and passing them in requests to fetch protected merchant data. For each request to fetch protected resources from the app backend, the session token needs to be passed in as an Authorization header in the following format:

Authorization: Bearer <session_token>

App Bridge provides utilities for getting session tokens and passing them into requests made to the app backend. For more information, refer to Get session tokens using App Bridge utilities.

Obtain session details manually

If your app isn't built using the Shopify App gem or the Shopify Node API, then use the following steps to help you manually decode the session token (JWT) and verify that it's valid. The session token is signed using the shared secret of your Shopify app.

Steps

  1. Decode the session token, verify the signature, and obtain the headers and payload.
  2. Extract the exp value from the payload.

    Verify that it's in the future.

  3. Extract the nbf value from the payload.

    Verify that it was in the past.

  4. Extract the iss and dest fields from the payload.

    The top level domains should match. The dest field specifies the shops the request originated from. For example, myshop.myshopify.com.

  5. Extract the aud value from the payload.

    Verify that it matches the API key of your app.

  6. Extract the sub value from the payload.

    This is the ID of the user that made the request.

If any of the above steps fail, discard and stop further processing of the request immediately, and respond with an error.

Verify the signature

Use the following steps to verify that the issued token has a valid signature. To verify that the signature is correct, you need to generate a new Base64url-encoded signature using the app’s shared secret.

Session tokens are signed using the HS256 algorithm. This is a symmetric algorithm. The signing key is the shared secret for your Shopify app. A session token is a JWT string with the following structure: <header>.<payload>.<signature>

All three sections are base64 encoded.

Steps

  1. Take the <header>.<payload> portion of the string and hash it with SHA-256.
  2. Sign the string using the HS256 algorithm by using the app’s secret as the signing key.
  3. Base64url-encode the result.
  4. Verify the result is the same as the signature sent with the session token.

When you're done

Your app should now work using session token authentication. When any network calls are made, you should see the session token being sent in the header:

Next steps

  • Make authenticated requests using Axios.
  • Use helper functions to fetch a session token from App Bridge and include them in requests being made to the app backend.
  • Convert a multi-page, server-side rendered (SSR) app to use App Bridge authentication with Turbolinks.
  • Learn how to build a Shopify app with Rails 6, React, and App Bridge authentication.
  • Learn how to build a Shopify app with Node and React.