Authenticate a server-side rendered embedded app using Rails and Turbolinks
This tutorial shows you how to convert your multi-page SSR app to use authentication based on session tokens with Turbolinks.
- You've created a public app or custom app from your Partner Dashboard.
- The app is embedded in Shopify admin.
Your app has the Shopify App gem version 17.1.0 or higher installed. The Shopify App gem version 17.0.5 and higher creates a JSON Web Token (JWT)-enabled app by default when you run the following terminal command:
Your app is enabled to use JWT authentication and session tokens.
You have a basic understanding of Turbolinks.
To use session tokens with your multi-page app using Turbolinks, implement the following conversion pattern:
Create an unauthenticated controller that renders a splash page when a user visits your app. This splash page communicates to users that your app is loading.
Use the splash page to do the following:
- Create a Shopify App Bridge instance.
- Retrieve and cache a session token within your app client.
- Install event listeners to set an
"Authorization": "Bearer <session token>"request header on the following events:
Install a timed event that continues to retrieve and cache session tokens every two seconds. This ensures that your session tokens are always valid.
Use Turbolinks to navigate to your app's authenticated home page or resource.
Enable Turbolinks on your app
Use the following steps to enable Turbolinks on your app.
turbolinksgem to your Gemfile:
turbolinkspackage to your application.
If you're working with an existing app and it uses webpack to manage its manifest files, then make sure that the following line is added to
Create a splash page
Your splash page is used to indicate that your app has begun to fetch a session token. When your app gets the token, it should navigate the user to the main view. The main view might contain protected or authenticated resources.
SplashPageControlleralong with a default index action and view:
splash_page#indexthe default root route for your app. Update the following code in your
Indicate a loading status in your splash page index view. Update
app/views/splash_page/index.html.erbto match the following code:
SplashPageControllerbehave as the default embedded app
app/controllers/splash_page_controller.rbto match the following code:
Protect the default
home_controller.rbto match the following code:
To handle changes in access scopes requested by your app, add the following configuration to
/app/config/initializers/shopify_app.rb. For more information on handling changes in access scopes, refer to the Shopify App gem.
Fetch and store session tokens
Create a Shopify App Bridge instance.
Fetch a session token and cache it.
Install event listeners on the
turbolinks:renderevents to add an
Install event listeners to add an
Authorizationrequest header on the following events:
Use Turbolinks to navigate to the
Add the following
app/views/layouts/embedded_app.html.erb. This parameter is used by Turbolinks to navigate back to this app when a session token has been fetched. In the following example, you're navigating to
Import the library method
shopify_app.js, include the following methods that fetch and store a session token every two seconds:
shopify_app.js, also include the following helper method and replace
'/home'with your app's
home_path. The helper method navigates your app using Turbolinks. It does this by determining whether the navigation is made on the initial load of your app.
shopify_app.js, add event listeners to the
turbolinks:renderevents. Set an
"Authorization": "Bearer <session token>"header during these events:
shopify_app.js, edit the
DOMContentLoadedevent listener to add the following instructions:
After a session token is retrieved,
Turbolinks.visit(data.loadPath) visits the
load_path parameter defined in
Your app continues to retrieve session tokens every two seconds.
Request authenticated resources
When a user visits your app, they should now briefly see a loading screen before they're taken to the Home view of your app. The Home view is authenticated by the
For demo purposes, we have created two additional authenticated controllers:
WidgetsController. The following steps describe how to create the
ProductsController and add a navigation link to the Home view.
ProductsControllerusing the Rails generator:
Add authentication to the
Create a view for the
app/views/products/index.html.erbto match the following code:
AuthenticatedControllerto authenticate pages of your app that are deep linked. This concern is available in Shopify App version 17.1.0:
app/views/home/index.html.erbto include a link to the product index view:
Your app can now access the authenticated
ProductsController from the
HomeController using session tokens.
Make sure shop records are updated
To ensure OAuth continues to work with session tokens, your app must update its shop records in the event a shop uninstalls your app. The app can receive notifications of these events by subscribing to the
The following sections show a Ruby implementation that subscribes to the webhook and updates the records.
Set up the webhook
add_webhook generator from the shopify_app gem to set up the
app/uninstalled webhook for the app. The following code adds the
app/uninstalled webhook to your app config and creates the
AppUninstalledJob job class so that you can add uninstallation handler logic.
Mark the shop record as uninstalled
To mark the record as uninstalled, you need to update the
AppUninstalledJob job class. In the following example, the app marks the shop as uninstalled by deleting the Shop record:
Define a background job
You need to define a background job to ensure that shops with existing installations also have the uninstall webhook set up. In the following example, the
RegisterWebhooksForActiveShop job is defined to iterate all shop records in the database and configure the webhooks.
Enqueue the background job
RegisterWebhooksForActiveShops background job to apply the webhook registration. For details on enqueuing ActiveJobs on Rails, refer to the Rails guides.