Skip to content

Commit

Permalink
Merge pull request #1714 from Shopify/zoey/improve-docs
Browse files Browse the repository at this point in the history
Update authentication page docs
  • Loading branch information
zzooeeyy authored Aug 18, 2023
2 parents cee94a6 + 4460b25 commit 0a9dbff
Showing 1 changed file with 61 additions and 56 deletions.
117 changes: 61 additions & 56 deletions docs/shopify_app/authentication.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,75 @@
# Authentication

The Shopify App gem implements [OAuth 2.0](https://shopify.dev/tutorials/authenticate-with-oauth) to get [access tokens](https://shopify.dev/concepts/about-apis/authentication#api-access-modes). These are used to authenticate requests made by the app to the Shopify API.
The Shopify App gem implements [OAuth 2.0](https://shopify.dev/tutorials/authenticate-with-oauth) to get [session tokens](https://shopify.dev/concepts/about-apis/authentication#api-access-modes). These are used to authenticate requests made by the app to the Shopify API.

By default, the gem generates an embedded app frontend that uses [Shopify App Bridge](https://shopify.dev/tools/app-bridge) to fetch [session tokens](https://shopify.dev/concepts/apps/building-embedded-apps-using-session-tokens). Session tokens are used by the embedded app to make authenticated requests to the app backend.

See [*Authenticate an embedded app using session tokens*](https://shopify.dev/tutorials/authenticate-your-app-using-session-tokens) to learn more.
See [*Getting started with session token authentication*](https://shopify.dev/docs/apps/auth/oauth/session-tokens/getting-started) to learn more.

> ⚠️ Be sure you understand the differences between the types of authentication schemes before reading this guide.
#### Table of contents

[OAuth callback](#oauth-callback)
* [OAuth callback](#oauth-callback)
* [Customizing callback controller](#customizing-callback-controller)
* [Run jobs after the OAuth flow](#run-jobs-after-the-oauth-flow)
* [Rotate API credentials](#rotate-api-credentials)
* [Making authenticated API requests after authorization](#making-authenticated-api-requests-after-authorization)

[Run jobs after the OAuth flow](#run-jobs-after-the-oauth-flow)
## OAuth callback

[Rotate API credentials](#rotate-api-credentials)
>**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.
[Available authentication mixins](#available-authentication-mixins)
* [`ShopifyApp::Authenticated`](#shopifyappauthenticated)
* [`ShopifyApp::EnsureAuthenticatedLinks`](#shopifyappensureauthenticatedlinks)
Upon completing the OAuth flow, Shopify calls the app at `ShopifyApp.configuration.login_callback_url`.

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

>**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. Logging into the shop and resetting the session
2. Storing the session to the `SessionRepository`
3. [Installing Webhooks](/docs/shopify_app/webhooks.md)
4. [Setting Scripttags](/docs/shopify_app/script-tags.md)
5. [Run jobs after the OAuth flow](#run-jobs-after-the-oauth-flow)
6. Redirecting to the return address

Upon completing the OAuth flow, Shopify calls the app at the `callback_path`. If the app needs to do some extra work, it can define and configure the route to a custom callback controller, inheriting from `ShopifyApp::CallbackController` and hook into or override any of the defined helper methods. The default callback controller already provides the following behaviour:
* Logging into the shop and resetting the session
* [Installing Webhooks](/docs/shopify_app/webhooks.md)
* [Setting Scripttags](/docs/shopify_app/script-tags.md)
* [Run jobs after the OAuth flow](#run-jobs-after-the-oauth-flow)
* Redirecting to the return address

## Run jobs after the OAuth flow
#### Customizing callback controller
If the app needs to do some extra work, it can define and configure the route to a custom callback controller.
Inheriting from `ShopifyApp::CallbackController` and hook into or override any of the defined helper methods.

Example:

1. Create the new custom callback controller
```ruby
# web/app/controllers/my_custom_callback_controller.rb

class MyCustomCallbackController < ShopifyApp::CallbackController
private

def install_webhooks(session)
# My custom override/definition to install webhooks
end
end
```

2. Override callback routing to this controller

```ruby
# web/config/routes.rb

Rails.application.routes.draw do
root to: "home#index"

# Overriding the callback controller to the new custom one.
# This must be added before mounting the ShopifyApp::Engine
get ShopifyApp.configuration.login_callback_url, to: 'my_custom_callback#callback'

mount ShopifyApp::Engine, at: "/api"

# other routes
end
```

### Run jobs after the OAuth flow

See [`ShopifyApp::AfterAuthenticateJob`](/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb).

Expand Down Expand Up @@ -63,7 +101,7 @@ If you want to perform that action only once, e.g. send a welcome email to the u

## Rotate API credentials

If your Shopify secret key is leaked, you can use the RotateShopifyTokenJob to perform [API Credential Rotation](https://help.shopify.com/en/api/getting-started/authentication/oauth/api-credential-rotation).
If your Shopify secret key is leaked, you can use the `RotateShopifyTokenJob` to perform [API Credential Rotation](https://help.shopify.com/en/api/getting-started/authentication/oauth/api-credential-rotation).

Before running the job, you'll need to generate a new secret key from your Shopify Partner dashboard, and update the `/config/initializers/shopify_app.rb` to hold your new and old secret keys:

Expand All @@ -86,43 +124,10 @@ strategy.options[:old_client_secret] = ShopifyApp.configuration.old_secret

> **Note:** If you are updating `shopify_app` from a version prior to 8.4.2 (and do not wish to run the default/install generator again), you will need to add [the following line](https://github.com/Shopify/shopify_app/blob/4f7e6cca2a472d8f7af44b938bd0fcafe4d8e88a/lib/generators/shopify_app/install/templates/shopify_provider.rb#L18) to `config/initializers/omniauth.rb`:
## Available authentication mixins

### `ShopifyApp::Authenticated`

The engine provides a [`ShopifyApp::Authenticated`](/app/controllers/concerns/shopify_app/authenticated.rb) concern which should be included in any controller that is intended to be behind Shopify OAuth. It adds `before_action`s to ensure that the user is authenticated and will redirect to the Shopify login page if not. It is best practice to include this concern in a base controller inheriting from your `ApplicationController`, from which all controllers that require Shopify authentication inherit.

*Example:*

```rb
class AuthenticatedController < ApplicationController
include ShopifyApp::Authenticated
end

class ApiController < AuthenticatedController
# Actions in this controller are protected
end
```

For backwards compatibility, the engine still provides a controller called `ShopifyApp::AuthenticatedController` which includes the `ShopifyApp::Authenticated` concern. Note that it inherits directly from `ActionController::Base`, so you will not be able to share functionality between it and your application's `ApplicationController`.

#### Embedded apps and `ShopifyApp::Authenticated`

Embedded Shopify Admin apps can only use the `ShopifyApp::Authenticated` controller concern *if* the requests originate from App Bridge's `authenticatedFetch` method. Those who include this concern in the `HomeController` or some other embedded controller will see what looks like an OAuth redirect loop as the `ShopifyApp::Authenticated` concern will be fighting with the App Bridge. For more details on how to handle embedded sessions, refer to [the session token documentation](https://shopify.dev/apps/auth/oauth/session-tokens).

### `ShopifyApp::EnsureAuthenticatedLinks`
## Making authenticated API requests after authorization
After the app is installed onto a shop and has been granted all necessary permission, a new session record will be added to `SessionRepository#shop_storage`, or `SessionRepository#user_storage` if online sessions are enabled.

The [`ShopifyApp::EnsureAuthenticatedLinks`](/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb) concern helps authenticate users that access protected pages of your app directly.

Include this concern in your app's `AuthenticatedController` if your app uses session tokens with [Turbolinks](https://github.com/turbolinks/turbolinks). It adds a `before_action` filter that detects whether a session token is present or not. If a session token is not found, the user is redirected to your app's splash page path (`root_path`) along with `return_to` and `shop` parameters.

*Example:*

```rb
class AuthenticatedController < ApplicationController
include ShopifyApp::EnsureAuthenticatedLinks
include ShopifyApp::Authenticated
end
```
When your app needs to make API requests to Shopify, `ShopifyApp`'s `ActiveSupport` controller concerns can help you retrieve the active session token from the repository to make the authenticate API call.

See [Authenticate server-side rendered embedded apps using Rails and Turbolinks](https://shopify.dev/tutorials/authenticate-server-side-rendered-embedded-apps-using-rails-and-turbolinks) for more information.
- ⚠️ See [Sessions](./sessions.md) page to understand how sessions work.
- ⚠️ See [Controller Concerns](./controller-concerns.md) page to understand when to use which concern.

0 comments on commit 0a9dbff

Please sign in to comment.