From 86f8fc1cfa81ead15925c09993dce7e1aa580ca1 Mon Sep 17 00:00:00 2001 From: Andy Waite Date: Fri, 28 Oct 2022 10:00:56 -0400 Subject: [PATCH] Improve upgrade docs --- docs/Troubleshooting.md | 40 ++++++++++++++++++++++++++++-- docs/Upgrading.md | 54 ++++++++++++++++++----------------------- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 11c1b1cbd..5b9539abb 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -3,7 +3,7 @@ #### Table of contents [Generators](#generators) - * [The `shopify_app:install` generator hangs](#the-shopifyappinstall-generator-hangs) + * [The `shopify_app:install` generator hangs](#the-shopify_appinstall-generator-hangs) [Rails](#rails) * [Known issues with Rails `v6.1`](#known-issues-with-rails-v61) @@ -18,6 +18,8 @@ * [My app can't make requests to the Shopify API](#my-app-cant-make-requests-to-the-shopify-api) * [I'm stuck in a redirect loop after OAuth](#im-stuck-in-a-redirect-loop-after-oauth) +[Debugging Tips](#debugging-tips) + ## Generators ### The shopify_app:install generator hangs @@ -143,9 +145,43 @@ X-Shopify-API-Request-Failure-Unauthorized: true Then, use the [Shopify App Bridge Redirect](https://shopify.dev/tools/app-bridge/actions/navigation/redirect) action to redirect your app frontend to the app login URL if this header is set. - ### I'm stuck in a redirect loop after OAuth In previous versions of `ShopifyApp::Authenticated` controller concern, App Bridge embedded apps were able to include the `Authenticated` controller concern in the `HomeController` and other embedded controllers. This is no longer supported due to browsers blocking 3rd party cookies to increase privacy. App Bridge 3 is needed to handle all embedded sessions. For more details on how to handle embeded sessions, refer to [the session token documentation](https://shopify.dev/apps/auth/oauth/session-tokens). + +### `redirect_uri is not whitelisted` + +* Ensure you have set the `HOST` environment variable to match your host's URL, e.g. `http://localhost:3000` or `https://my-host-name.trycloudflare.com`. +* Update the app's URL and whitelisted URLs in App Setup on https://partners.shopify.com + +### `This app can’t load due to an issue with browser cookies` + +This can be caused by an infinite redirect due to a coding error +To investigate the cause, you can add a breakpoint or logging to the `rescue` clause of `ShopifyApp::CallbackController`. + +One possible cause is that for XHR requests, the `Authenticated` concern should be used, rather than `RequireKnownShop`. +See below for further details. + +## Controller Concerns +### Authenticated vs RequireKnownShop +The gem heavily relies on the `current_shopify_domain` helper to contextualize a request to a given Shopify shop. This helper is set in different and conflicting ways if the request is authenticated or not. + +Because of these conflicting approaches the `Authenticated` (for use in authenticated requests) and `RequireKnownShop` (for use in unauthenticated requests) controller concerns must *never* be included within the same controller. + +#### Authenticated Requests +For authenticated requests, use the [`Authenticated` controller concern](https://github.com/Shopify/shopify_app/blob/main/app/controllers/concerns/shopify_app/authenticated.rb). The `current_shopify_domain` is set from the JWT for these requests. + +#### Unauthenticated Requests +For unauthenticated requests, use the [`RequireKnownShop` controller concern](https://github.com/Shopify/shopify_app/blob/main/app/controllers/concerns/shopify_app/require_known_shop.rb). The `current_shopify_domain` is set from the query string parameters that are passed. + +## Debugging Tips + +If you do run into issues with the gem there are two useful techniques to apply: Adding log statements, and using an interactive debugger, such as `pry`. + +You can temporarily add log statements or debugger calls to the `shopify_app` or `shopify-api-ruby` gems: + * You can modify a gem using [`bundle open`](https://boringrails.com/tips/bundle-open-debug-gems) + * Alternatively, you can your modify your `Gemfile` to use local locally checked out gems with the the [`path` option](https://bundler.io/man/gemfile.5.html). + +Note that if you make changes to a gem, you will need to restart the app for the changes to be applied. diff --git a/docs/Upgrading.md b/docs/Upgrading.md index c6c9f5126..9ff249fc3 100644 --- a/docs/Upgrading.md +++ b/docs/Upgrading.md @@ -4,6 +4,8 @@ This file documents important changes needed to upgrade your app's Shopify App v #### Table of contents +[General Advice](#general-advice) + [Upgrading to `v20.2.0`](#upgrading-to-v2020) [Upgrading to `v20.1.0`](#upgrading-to-v2010) @@ -20,7 +22,20 @@ This file documents important changes needed to upgrade your app's Shopify App v [Upgrading from `v8.6` to `v9.0.0`](#upgrading-from-v86-to-v900) +## General Advice + +Although we strive to make upgrades as smooth as possible, some effort may be required to stay up to date with the latest changes to `shopify_app`. + +We strongly recommend you avoid 'monkeypatching' any existing code from `ShopifyApp`, e.g. by inheriting from `ShopifyApp` and then overriding particular methods. This can result in difficult upgrades. If your app does so, you will need to carefully check the gem's internal changes when upgrading. + +If you need to upgrade by more than one major version (e.g. from v18 to v20), we recommend doing one at a time. Deploy each into production to help to detect problems earlier. + +We also recommend the use of a staging site which matches your production environment as closely as possible. + +If you do run into issues, we recommend looking at our [debugging tips.](https://github.com/Shopify/shopify_app/blob/main/docs/Troubleshooting.md#debugging-tips) + ## Upgrading to `v20.2.0` + All custom errors defined inline within the `ShopifyApp` gem have been moved to `lib/shopify_app/errors.rb`. - If you rescue any errors defined in this gem, you will need to rename them to match their new namespacing. @@ -36,8 +51,9 @@ Note that the following steps are *optional* and only apply to **embedded** appl ## Upgrading to `v19.0.0` -This update moves API authentication logic from this gem to the [`shopify_api`](https://github.com/Shopify/shopify-api-ruby) -gem. +*This change introduced a major change of strategy regarding sessions.* Due to security changes with browsers, support for cookie based sessions was dropped. JWT is now the only supported method for managing sessions. + +As part of that change, this update moves API authentication logic from this gem to the [`shopify_api`](https://github.com/Shopify/shopify-api-ruby) gem. ### High-level process @@ -53,13 +69,16 @@ gem. ### Specific cases -#### Shopify user id in session +#### Shopify user ID in session Previously, we set the entire app user object in the `session` object. As of v19, since we no longer save the app user to the session (but only the shopify user id), we now store it as `session[:shopify_user_id]`. Please make sure to update any references to that object. #### Webhook Jobs +It is assumed that you have an ActiveJob implementation configured for `perform_later`, e.g. Sidekiq. +Ensure your jobs inherit from `ApplicationJob` or `ActiveJob::Base`. + Add a new `handle` method to existing webhook jobs to go through the updated `shopify_api` gem. ```ruby @@ -95,32 +114,7 @@ Shopify API session, or `nil` if no such session is available. #### Setting up `ShopifyAPI::Context` -The `shopify_app` initializer must configure the `ShopifyAPI::Context`. The Rails generator will -generate a block in the `shopify_app` initializer. To do so manually, ensure the following is -part of the `after_initialize` block in `shopify_app.rb`. - -```ruby -Rails.application.config.after_initialize do - if ShopifyApp.configuration.api_key.present? && ShopifyApp.configuration.secret.present? - ShopifyAPI::Context.setup( - api_key: ShopifyApp.configuration.api_key, - api_secret_key: ShopifyApp.configuration.secret, - old_api_secret_key: ShopifyApp.configuration.old_secret, - api_version: ShopifyApp.configuration.api_version, - host_name: URI(ENV.fetch('HOST', '')).host || '', - scope: ShopifyApp.configuration.scope, - is_private: !ENV.fetch('SHOPIFY_APP_PRIVATE_SHOP', '').empty?, - is_embedded: ShopifyApp.configuration.embedded_app, - session_storage: ShopifyApp::SessionRepository, - logger: Rails.logger, - private_shop: ENV.fetch('SHOPIFY_APP_PRIVATE_SHOP', nil), - user_agent_prefix: "ShopifyApp/#{ShopifyApp::VERSION}" - ) - - ShopifyApp::WebhooksManager.add_registrations - end -end -``` +The `shopify_app` initializer must configure the `ShopifyAPI::Context`. The Rails generator will generate a block in the `shopify_app` initializer. To do so manually, you can refer to `after_initialize` block in the [template]((https://github.com/Shopify/shopify_app/blob/main/lib/generators/shopify_app/install/templates/shopify_app.rb.tt). ## Upgrading to `v18.1.2` @@ -128,7 +122,7 @@ Version 18.1.2 replaces the deprecated EASDK redirect with an App Bridge 2 redir ## Upgrading to `v17.2.0` -### Different SameSite cookie attribute behaviour +### Different SameSite cookie attribute behavior To support Rails `v6.1`, the [`SameSiteCookieMiddleware`](/lib/shopify_app/middleware/same_site_cookie_middleware.rb) was updated to configure cookies to `SameSite=None` if the app is embedded. Before this release, cookies were configured to `SameSite=None` only if this attribute had not previously been set before.