Skip to content

Commit

Permalink
Merge pull request #1834 from Shopify/add-docs
Browse files Browse the repository at this point in the history
Add new auth strategy docs & set token exchange as default configuration from rails generator
  • Loading branch information
zzooeeyy committed May 2, 2024
2 parents ca0aeb0 + 75e39bb commit 44079b0
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 32 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
Unreleased
----------
* Add new zero redirect authorization strategy - `Token Exchange`.
- This strategy replaces the existing OAuth flow for embedded apps and remove the redirects that were previously necessary to complete OAuth.
See ["New embedded app authorization strategy"](/README.md/#new-embedded-app-authorization-strategy) for how to enable this feature.
- Related PRs: [#1817](https://github.com/Shopify/shopify_app/pull/1817),
[#1818](https://github.com/Shopify/shopify_app/pull/1818),
[#1819](https://github.com/Shopify/shopify_app/pull/1819),
[#1821](https://github.com/Shopify/shopify_app/pull/1821),
[#1822](https://github.com/Shopify/shopify_app/pull/1822),
[#1823](https://github.com/Shopify/shopify_app/pull/1823),
[#1832](https://github.com/Shopify/shopify_app/pull/1832),
[#1833](https://github.com/Shopify/shopify_app/pull/1833),
[#1834](https://github.com/Shopify/shopify_app/pull/1834),
[#1836](https://github.com/Shopify/shopify_app/pull/1836),
* Bumps `shopify_api` to `14.3.0` [1832](https://github.com/Shopify/shopify_app/pull/1832)
* Support `id_token` from URL param [1832](https://github.com/Shopify/shopify_app/pull/1832)
* Extracted controller concern `WithShopifyIdToken`
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,44 @@ These routes are configurable. See the more detailed [*Engine*](/docs/shopify_ap

To learn more about how this gem authenticates with Shopify, see [*Authentication*](/docs/shopify_app/authentication.md).

### New embedded app authorization strategy (Token Exchange)

> [!TIP]
> If you are building an embedded app, we **strongly** recommend using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
> with [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange) instead of the legacy authorization code grant flow.
We've introduced a new installation and authorization strategy for **embedded apps** that
eliminates the redirects that were previously necessary.
It replaces the existing [installation and authorization code grant flow](https://shopify.dev/docs/apps/auth/get-access-tokens/authorization-code-grant).

This is achieved by using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
to handle automatic app installations and scope updates, while utilizing
[token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange) to retrieve an access token for
authenticated API access.

##### Enabling this new strategy in your app

1. Enable [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
by configuring your scopes [through the Shopify CLI](https://shopify.dev/docs/apps/tools/cli/configuration).
2. Enable the new auth strategy in your app's ShopifyApp configuration file.

```ruby
# config/initializers/shopify_app.rb
ShopifyApp.configure do |config|
#.....
config.embedded_app = true
config.new_embedded_auth_strategy = true

# If your app is configured to use online sessions, you can enable session expiry date check so a new access token
# is fetched automatically when the session expires.
# See expiry date check docs: https://github.com/Shopify/shopify_app/blob/main/docs/shopify_app/sessions.md#expiry-date
config.check_session_expiry_date = true
...
end

```
3. Enjoy a smoother and faster app installation process.

### API Versioning

[Shopify's API is versioned](https://shopify.dev/concepts/about-apis/versioning). With Shopify App `v1.11.0`, the included Shopify API gem allows developers to specify and update the Shopify API version they want their app or service to use. The Shopify API gem also surfaces warnings to Rails apps about [deprecated endpoints, GraphQL fields and more](https://shopify.dev/concepts/about-apis/versioning#deprecation-practices).
Expand Down
8 changes: 8 additions & 0 deletions docs/Upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ This file documents important changes needed to upgrade your app's Shopify App v

[Unreleased](#unreleased)

[Upgrading to `v22.2.0`](#upgrading-to-v2220)

[Upgrading to `v22.0.0`](#upgrading-to-v2200)

[Upgrading to `v20.3.0`](#upgrading-to-v2030)
Expand Down Expand Up @@ -57,6 +59,12 @@ class from the `shopify_api` gem instead. A search and replace should be enough
- `ShopifyAPI::Auth::JwtPayload` is a superset of the `ShopifyApp::JWT` class, and contains methods that were available in `ShopifyApp::JWT`.
- `ShopifyAPI::Auth::JwtPayload` raises `ShopifyAPI::Errors::InvalidJwtTokenError` if the token is invalid.

## Upgrading to `v22.2.0`
#### Added new feature for zero redirect embedded app authorization flow - Token Exchange
A new embedded app authorization strategy has been introduced in `v22.2.0` that eliminates the redirects that were previously necessary for OAuth.
It can replace the existing installation and authorization code grant flow.
See [new embedded app authorization strategy](./README.md#new-embedded-app-authorization-strategy) for more information.

## Upgrading to `v22.0.0`
#### Dropped support for Ruby 2.x
Support for Ruby 2.x has been dropped as it is no longer supported. You'll need to upgrade to 3.x.x
Expand Down
75 changes: 69 additions & 6 deletions docs/shopify_app/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,73 @@ See [*Getting started with session token authentication*](https://shopify.dev/do
#### Table of contents

* [OAuth callback](#oauth-callback)
* [Customizing callback controller](#customizing-callback-controller)
* [Supported types of OAuth Flow](#supported-types-of-oauth)
* [Token Exchange](#token-exchange)
* [Authorization Code Grant Flow](#authorization-code-grant-flow)
* [OAuth callback](#oauth-callback)
* [Customizing callback controller](#customizing-callback-controller)
* [Detecting scope changes](#detecting-scope-changes-1)
* [Run jobs after the OAuth flow](#post-authenticate-tasks)
* [Rotate API credentials](#rotate-api-credentials)
* [Making authenticated API requests after authorization](#making-authenticated-api-requests-after-authorization)

## OAuth callback
## Supported types of OAuth
> [!TIP]
> If you are building an embedded app, we **strongly** recommend using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
with [token exchange](#token-exchange) instead of the authorization code grant flow.

>**Note:** In Shopify App version 8.4.0, we have extracted the callback logic in its own controller. If you are upgrading from a version older than 8.4.0 the callback action and related helper methods were defined in `ShopifyApp::SessionsController` ==> you will have to extend `ShopifyApp::CallbackController` instead and port your logic to the new controller.
1. [Token Exchange](#token-exchange)
- Recommended and is only available for embedded apps
- Doesn't require redirects, which makes authorization faster and prevents flickering when loading the app
- Access scope changes are handled by Shopify when you use [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
2. [Authorization Code Grant Flow](#authorization-code-grant-flow)
- Suitable for non-embedded apps
- Installations, and access scope changes are managed by the app

Upon completing the OAuth flow, Shopify calls the app at `ShopifyApp.configuration.login_callback_url`.
## Token Exchange

OAuth process by exchanging the current user's [session token (shopify id token)](https://shopify.dev/docs/apps/auth/session-tokens) for an
[access token](https://shopify.dev/docs/apps/auth/access-token-types/online.md) to make
authenticated Shopify API queries. This will replace authorization code grant flow completely when your app is configured with [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).

To enable token exchange authorization strategy, you can follow the steps in ["New embedded app authorization strategy"](/README.md#new-embedded-app-authorization-strategy).
Upon completion of the token exchange to get the access token, [post authenticated tasks](#post-authenticate-tasks) will be run.

Learn more about:
- [How token exchange works](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange)
- [Using Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
- [Configuring access scopes through the Shopify CLI](https://shopify.dev/docs/apps/tools/cli/configuration)

#### Handling invalid access tokens
If the access token used to make an API call is invalid, the token exchange strategy will handle the error and try to retrieve a new access token before retrying
the same operation.
See ["Re-fetching an access token when API returns Unauthorized"](/docs/shopify_app/sessions.md#re-fetching-an-access-token-when-api-returns-unauthorized) section for more information.

#### Detecting scope changes

##### Shopify managed installation
If your access scopes are [configured through the Shopify CLI](https://shopify.dev/docs/apps/tools/cli/configuration), scope changes will be handled by Shopify automatically.
Learn more about [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).
Using token exchange will ensure that the access token retrieved will always have the latest access scopes granted by the user.

## Authorization Code Grant Flow
Authorization code grant flow is the OAuth flow that requires the app to redirect the user
to Shopify for installation/authorization of the app to access the shop's data. It is still required for apps that are not embedded.

To perform [authorization code grant flow](https://shopify.dev/docs/apps/auth/get-access-tokens/authorization-code-grant), you app will need to handle
[begin OAuth](#begin-oauth) and [OAuth callback](#oauth-callback) routes.

### Begin OAuth
ShopifyApp automatically redirects the user to Shopify to complete OAuth to install the app when the `ShopifyApp.configuration.login_url` is reached.
Behind the scenes the ShopifyApp gem starts the process by calling `ShopifyAPI::Auth::Oauth.begin_auth` to build the
redirect URL with necessary parameters like the OAuth callback URL, scopes requested, type of access token (offline or online) requested, etc.
The ShopifyApp gem then redirect the merchant to Shopify, to ask for permission to install the app. (See [ShopifyApp::SessionsController.redirect_to_begin_oauth](https://github.com/Shopify/shopify_app/blob/main/app/controllers/shopify_app/sessions_controller.rb#L76-L96)
for detailed implementation)

### OAuth callback

Shopify will redirect the merchant back to your app's callback URL once they approve the app installation.
Upon completing the OAuth flow, Shopify calls the app at `ShopifyApp.configuration.login_callback_url`. (This was provided to Shopify in the OAuth begin URL parameters)

The default callback controller [`ShopifyApp::CallbackController`](../../app/controllers/shopify_app/callback_controller.rb) provides the following behaviour:

Expand Down Expand Up @@ -63,7 +119,14 @@ Rails.application.routes.draw do
end
```

### Post Authenticate tasks
### Detecting scope changes
When the OAuth process is completed, the created session has a `scope` field which holds all of the access scopes that were requested from the merchant at the time.

When an app's access scopes change, it needs to request merchants to go through OAuth again to renew its permissions.

See [Handling changes in access scopes](/docs/shopify_app/handling-access-scopes-changes.md).

## Post Authenticate tasks
After authentication is complete, a few tasks are run by default by PostAuthenticateTasks:
1. [Installing Webhooks](/docs/shopify_app/webhooks.md)
2. [Run configured after_authenticate_job](#after_authenticate_job)
Expand Down

0 comments on commit 44079b0

Please sign in to comment.