shopify_app 21.6.0 → 22.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/ISSUE_TEMPLATE/bug-report.md +23 -18
- data/.github/workflows/build.yml +2 -2
- data/.github/workflows/release.yml +1 -1
- data/.github/workflows/rubocop.yml +1 -2
- data/.nvmrc +1 -1
- data/.rubocop.yml +0 -1
- data/CHANGELOG.md +115 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +1 -6
- data/Gemfile.lock +99 -96
- data/README.md +47 -2
- data/app/assets/javascripts/shopify_app/redirect.js +3 -10
- data/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb +5 -1
- data/app/controllers/concerns/shopify_app/ensure_has_session.rb +11 -5
- data/app/controllers/concerns/shopify_app/ensure_installed.rb +10 -4
- data/app/controllers/concerns/shopify_app/shop_access_scopes_verification.rb +5 -1
- data/app/controllers/shopify_app/callback_controller.rb +39 -18
- data/app/controllers/shopify_app/sessions_controller.rb +25 -4
- data/app/views/shopify_app/layouts/app_bridge.html.erb +17 -0
- data/app/views/shopify_app/sessions/patch_shopify_id_token.html.erb +0 -0
- data/app/views/shopify_app/shared/redirect.html.erb +10 -1
- data/config/locales/cs.yml +0 -18
- data/config/locales/da.yml +0 -15
- data/config/locales/de.yml +0 -17
- data/config/locales/en.yml +0 -11
- data/config/locales/es.yml +0 -17
- data/config/locales/fi.yml +0 -15
- data/config/locales/fr.yml +0 -18
- data/config/locales/it.yml +0 -16
- data/config/locales/ja.yml +0 -12
- data/config/locales/ko.yml +0 -14
- data/config/locales/nb.yml +0 -16
- data/config/locales/nl.yml +0 -16
- data/config/locales/pl.yml +0 -16
- data/config/locales/pt-BR.yml +0 -16
- data/config/locales/pt-PT.yml +0 -17
- data/config/locales/sv.yml +0 -16
- data/config/locales/th.yml +0 -15
- data/config/locales/tr.yml +0 -17
- data/config/locales/vi.yml +0 -17
- data/config/locales/zh-CN.yml +0 -11
- data/config/locales/zh-TW.yml +0 -11
- data/config/routes.rb +2 -1
- data/docs/Quickstart.md +9 -2
- data/docs/Troubleshooting.md +0 -23
- data/docs/Upgrading.md +64 -1
- data/docs/shopify_app/authentication.md +179 -58
- data/docs/shopify_app/controller-concerns.md +53 -12
- data/docs/shopify_app/generators.md +2 -2
- data/docs/shopify_app/sessions.md +358 -0
- data/docs/shopify_app/webhooks.md +88 -11
- data/karma.conf.js +6 -4
- data/lib/generators/shopify_app/add_declarative_webhook/add_declarative_webhook_generator.rb +53 -0
- data/lib/generators/shopify_app/add_declarative_webhook/templates/webhook_controller.rb.tt +13 -0
- data/lib/generators/shopify_app/add_declarative_webhook/templates/webhook_job.rb.tt +15 -0
- data/lib/generators/shopify_app/{add_gdpr_jobs/add_gdpr_jobs_generator.rb → add_privacy_jobs/add_privacy_jobs_generator.rb} +1 -1
- data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +6 -1
- data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt +1 -0
- data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +5 -2
- data/lib/generators/shopify_app/shopify_app_generator.rb +1 -1
- data/lib/generators/shopify_app/user_model/templates/db/migrate/add_user_expires_at_column.erb +5 -0
- data/lib/generators/shopify_app/user_model/user_model_generator.rb +20 -0
- data/lib/shopify_app/admin_api/with_token_refetch.rb +27 -0
- data/lib/shopify_app/auth/post_authenticate_tasks.rb +48 -0
- data/lib/shopify_app/auth/token_exchange.rb +73 -0
- data/lib/shopify_app/configuration.rb +69 -1
- data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +1 -1
- data/lib/shopify_app/controller_concerns/csrf_protection.rb +2 -1
- data/lib/shopify_app/controller_concerns/embedded_app.rb +42 -3
- data/lib/shopify_app/controller_concerns/ensure_billing.rb +14 -3
- data/lib/shopify_app/controller_concerns/frame_ancestors.rb +1 -1
- data/lib/shopify_app/controller_concerns/localization.rb +11 -8
- data/lib/shopify_app/controller_concerns/login_protection.rb +34 -38
- data/lib/shopify_app/controller_concerns/redirect_for_embedded.rb +5 -0
- data/lib/shopify_app/controller_concerns/sanitized_params.rb +4 -0
- data/lib/shopify_app/controller_concerns/token_exchange.rb +111 -0
- data/lib/shopify_app/controller_concerns/with_shopify_id_token.rb +48 -0
- data/lib/shopify_app/engine.rb +5 -11
- data/lib/shopify_app/managers/webhooks_manager.rb +6 -2
- data/lib/shopify_app/middleware/jwt_middleware.rb +13 -9
- data/lib/shopify_app/session/in_memory_user_session_store.rb +1 -1
- data/lib/shopify_app/session/jwt.rb +9 -0
- data/lib/shopify_app/session/session_repository.rb +49 -8
- data/lib/shopify_app/session/shop_session_storage.rb +4 -0
- data/lib/shopify_app/session/shop_session_storage_with_scopes.rb +4 -0
- data/lib/shopify_app/session/user_session_storage.rb +4 -0
- data/lib/shopify_app/session/user_session_storage_with_scopes.rb +25 -0
- data/lib/shopify_app/test_helpers/shopify_session_helper.rb +1 -0
- data/lib/shopify_app/utils.rb +14 -1
- data/lib/shopify_app/version.rb +1 -1
- data/lib/shopify_app.rb +9 -3
- data/package.json +5 -6
- data/shopify_app.gemspec +4 -4
- data/yarn.lock +2134 -3905
- metadata +51 -60
- data/.github/workflows/stale.yml +0 -43
- data/app/assets/images/storage_access.svg +0 -1
- data/app/assets/javascripts/shopify_app/app_bridge_3.1.1.js +0 -10
- data/app/assets/javascripts/shopify_app/app_bridge_redirect.js +0 -22
- data/app/assets/javascripts/shopify_app/app_bridge_utils_3.1.1.js +0 -1
- data/app/controllers/concerns/shopify_app/authenticated.rb +0 -17
- data/app/controllers/concerns/shopify_app/require_known_shop.rb +0 -16
- data/docs/shopify_app/script-tags.md +0 -28
- data/docs/shopify_app/session-repository.md +0 -79
- data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +0 -42
- data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +0 -63
- data/lib/shopify_app/controller_concerns/itp.rb +0 -50
- data/lib/shopify_app/jobs/scripttags_manager_job.rb +0 -16
- data/lib/shopify_app/managers/scripttags_manager.rb +0 -85
- /data/lib/generators/shopify_app/{add_gdpr_jobs → add_privacy_jobs}/templates/customers_data_request_job.rb.tt +0 -0
- /data/lib/generators/shopify_app/{add_gdpr_jobs → add_privacy_jobs}/templates/customers_redact_job.rb.tt +0 -0
- /data/lib/generators/shopify_app/{add_gdpr_jobs → add_privacy_jobs}/templates/shop_redact_job.rb.tt +0 -0
data/config/locales/pt-BR.yml
CHANGED
@@ -3,19 +3,3 @@ pt-BR:
|
|
3
3
|
logged_out: Você saiu.
|
4
4
|
could_not_log_in: Não foi possível fazer login na Shopify store
|
5
5
|
invalid_shop_url: Domínio de loja inválido
|
6
|
-
enable_cookies_heading: Habilitar cookies de %{app}
|
7
|
-
enable_cookies_body: Você precisa habilitar manualmente os cookies neste navegador
|
8
|
-
para usar %{app} dentro da Shopify.
|
9
|
-
enable_cookies_footer: Os cookies permitem que o app o autentique armazenando temporariamente
|
10
|
-
suas preferências e dados pessoais. Eles expiram depois de 30 dias.
|
11
|
-
enable_cookies_action: Habilitar cookies
|
12
|
-
top_level_interaction_heading: Seu navegador precisa autenticar %{app}
|
13
|
-
top_level_interaction_body: Seu navegador exige que apps como o %{app} consultem
|
14
|
-
você sobre o acesso a cookies antes que a Shopify os abra.
|
15
|
-
top_level_interaction_action: Continuar
|
16
|
-
request_storage_access_heading: "%{app} precisa acessar cookies"
|
17
|
-
request_storage_access_body: Isso permite que o app autentique você armazenando
|
18
|
-
temporariamente seus dados pessoais. Clique em continuar e permita os cookies
|
19
|
-
para usar o app.
|
20
|
-
request_storage_access_footer: Os cookies expiram depois de 30 dias.
|
21
|
-
request_storage_access_action: Continuar
|
data/config/locales/pt-PT.yml
CHANGED
@@ -3,20 +3,3 @@ pt-PT:
|
|
3
3
|
logged_out: Terminou a sessão com sucesso
|
4
4
|
could_not_log_in: Não foi possível iniciar sessão na loja da Shopify
|
5
5
|
invalid_shop_url: Domínio de loja inválido
|
6
|
-
enable_cookies_heading: Ativar cookies de %{app}
|
7
|
-
enable_cookies_body: Tem de ativar manualmente os cookies neste navegador para utilizar
|
8
|
-
%{app} dentro da Shopify.
|
9
|
-
enable_cookies_footer: Os cookies permitem que a aplicação o autentique armazenando
|
10
|
-
temporariamente as suas preferências e informações pessoais. Expiram ao fim de
|
11
|
-
30 dias.
|
12
|
-
enable_cookies_action: Ativar cookies
|
13
|
-
top_level_interaction_heading: O seu navegador tem de autenticar %{app}
|
14
|
-
top_level_interaction_body: O seu navegador exige que aplicações como %{app} lhe
|
15
|
-
solicitem o acesso de cookies, antes que a Shopify as possa abrir.
|
16
|
-
top_level_interaction_action: Continuar
|
17
|
-
request_storage_access_heading: "%{app} tem de aceder a cookies"
|
18
|
-
request_storage_access_body: Isto permite que a aplicação o autentique armazenando
|
19
|
-
temporariamente as suas informações pessoais. Clique em continuar e permita os
|
20
|
-
cookies para utilizar a aplicação.
|
21
|
-
request_storage_access_footer: Os cookies expiram ao fim de 30 dias.
|
22
|
-
request_storage_access_action: Continuar
|
data/config/locales/sv.yml
CHANGED
@@ -3,19 +3,3 @@ sv:
|
|
3
3
|
logged_out: Har loggats ut
|
4
4
|
could_not_log_in: Det gick inte att logga in i Shopify-butiken
|
5
5
|
invalid_shop_url: Ogiltig butiksdomän
|
6
|
-
enable_cookies_heading: Aktivera cookies från %{app}
|
7
|
-
enable_cookies_body: Du måste aktivera cookies manuellt i den här webbläsaren för
|
8
|
-
att kunna använda %{app} inom Shopify.
|
9
|
-
enable_cookies_footer: Cookies låter appen autentisera dig genom att tillfälligt
|
10
|
-
lagra dina inställningar och personuppgifter. De upphör efter 30 dagar.
|
11
|
-
enable_cookies_action: Aktivera cookies
|
12
|
-
top_level_interaction_heading: Din webbläsare måste verifiera %{app}
|
13
|
-
top_level_interaction_body: Din webbläsare kräver att appar som %{app} frågar dig
|
14
|
-
om tillgång till cookies innan Shopify kan öppna den för dig.
|
15
|
-
top_level_interaction_action: Fortsätt
|
16
|
-
request_storage_access_heading: "%{app} behöver tillgång till cookies"
|
17
|
-
request_storage_access_body: Detta gör det möjligt för appen att autentisera dig
|
18
|
-
genom att tillfälligt lagra din personliga information. Klicka på fortsätt och
|
19
|
-
tillåta cookies att använda appen.
|
20
|
-
request_storage_access_footer: Cookies upphör efter 30 dagar.
|
21
|
-
request_storage_access_action: Fortsätt
|
data/config/locales/th.yml
CHANGED
@@ -3,18 +3,3 @@ th:
|
|
3
3
|
logged_out: ออกจากระบบสำเร็จ
|
4
4
|
could_not_log_in: ไม่สามารถเข้าสู่ระบบร้านค้า Shopify ได้
|
5
5
|
invalid_shop_url: โดเมนร้านค้าไม่ถูกต้อง
|
6
|
-
enable_cookies_heading: เปิดใช้คุกกี้จาก %{app}
|
7
|
-
enable_cookies_body: คุณต้องเปิดใช้คุกกี้ด้วยตนเองในเบราว์เซอร์นี้เพื่อใช้งาน %{app}
|
8
|
-
ภายใน Shopify
|
9
|
-
enable_cookies_footer: คุกกี้ช่วยให้แอปตรวจสอบความถูกต้องของคุณด้วยการจัดเก็บความชื่นชอบและข้อมูลส่วนตัวของคุณชั่วคราว
|
10
|
-
คุกกี้จะหมดอายุหลังจาก 30 วัน
|
11
|
-
enable_cookies_action: เปิดใช้คุกกี้
|
12
|
-
top_level_interaction_heading: เบราว์เซอร์ของคุณต้องรับรองความถูกต้องของ %{app}
|
13
|
-
top_level_interaction_body: เบราว์เซอร์ของคุณต้องการแอปอย่าง %{app} เพื่อขอให้คุณเข้าถึงคุกกี้ก่อนที่
|
14
|
-
Shopify จะสามารถเปิดมันให้คุณได้
|
15
|
-
top_level_interaction_action: ดำเนินการต่อ
|
16
|
-
request_storage_access_heading: "%{app} ต้องการสิทธิ์การเข้าถึงคุกกี้"
|
17
|
-
request_storage_access_body: สิ่งนี้ช่วยให้แอปตรวจสอบความถูกต้องของคุณด้วยการจัดเก็บข้อมูลส่วนตัวของคุณชั่วคราว
|
18
|
-
คลิกดำเนินการต่อและอนุญาตให้คุกกี้ใช้แอป
|
19
|
-
request_storage_access_footer: คุกกี้จะหมดอายุหลังจาก 30 วัน
|
20
|
-
request_storage_access_action: ดำเนินการต่อ
|
data/config/locales/tr.yml
CHANGED
@@ -3,20 +3,3 @@ tr:
|
|
3
3
|
logged_out: Oturum başarıyla kapatıldı
|
4
4
|
could_not_log_in: Shopify mağazasında oturum açılamadı
|
5
5
|
invalid_shop_url: Geçersiz mağaza alan adı
|
6
|
-
enable_cookies_heading: "%{app} uygulamasından çerezleri etkinleştir"
|
7
|
-
enable_cookies_body: "%{app} uygulamasını Shopify içinde kullanabilmek için bu tarayıcıda
|
8
|
-
çerezleri manuel olarak etkinleştirmelisiniz."
|
9
|
-
enable_cookies_footer: Çerezler, tercihlerinizi ve kişisel bilgilerinizi geçici
|
10
|
-
olarak saklayıp uygulamanın kimliğinizi doğrulamasına imkan tanır. Çerezlerin
|
11
|
-
süresi 30 gün sonra sonra sona erer.
|
12
|
-
enable_cookies_action: Çerezleri etkinleştir
|
13
|
-
top_level_interaction_heading: Tarayıcınızın %{app} kimliğini doğrulaması gerekiyor
|
14
|
-
top_level_interaction_body: Tarayıcınız, Shopify tarafından açılmadan önce %{app}
|
15
|
-
gibi uygulamaların sizden çerezlere erişim izni istemesini zorunlu tutuyor.
|
16
|
-
top_level_interaction_action: Devam
|
17
|
-
request_storage_access_heading: "%{app} uygulamasının çerezlere erişmesi gerekiyor"
|
18
|
-
request_storage_access_body: Böylece uygulama, kişisel bilgilerinizi geçici olarak
|
19
|
-
saklayıp kimliğinizi doğrulayabilir. Devam et'e tıklayın ve çerezlerin uygulamayı
|
20
|
-
kullanmasına izin verin.
|
21
|
-
request_storage_access_footer: Çerezlerin süresi 30 gün sonra sonra sona erer.
|
22
|
-
request_storage_access_action: Devam
|
data/config/locales/vi.yml
CHANGED
@@ -3,20 +3,3 @@ vi:
|
|
3
3
|
logged_out: Đã đăng xuất thành công
|
4
4
|
could_not_log_in: Không thể đăng nhập vào cửa hàng trên Shopify
|
5
5
|
invalid_shop_url: Miền cửa hàng không hợp lệ
|
6
|
-
enable_cookies_heading: Bật cookie từ %{app}
|
7
|
-
enable_cookies_body: Bạn phải bật cookie trong trình duyệt này theo cách thủ công
|
8
|
-
để sử dụng %{app} trong Shopify.
|
9
|
-
enable_cookies_footer: Cookie cho phép ứng dụng xác thực bạn bằng cách tạm thời
|
10
|
-
lưu trữ tùy chọn và thông tin cá nhân của bạn. Những thông tin này sẽ hết hạn
|
11
|
-
sau 30 ngày.
|
12
|
-
enable_cookies_action: Bật cookie
|
13
|
-
top_level_interaction_heading: Trình duyệt của bạn cần xác thực %{app}
|
14
|
-
top_level_interaction_body: Trình duyệt của bạn cần các ứng dụng như %{app} để yêu
|
15
|
-
cầu quyền truy cập vào cookie thì Shopify mới có thể mở giúp bạn.
|
16
|
-
top_level_interaction_action: Tiếp tục
|
17
|
-
request_storage_access_heading: "%{app} cần quyền truy cập cookie"
|
18
|
-
request_storage_access_body: Nhờ vậy, ứng dụng có thể xác thực bạn bằng cách tạm
|
19
|
-
thời lưu trữ thông tin cá nhân của bạn. Nhấp vào tiếp tục và cho phép cookie sử
|
20
|
-
dụng ứng dụng.
|
21
|
-
request_storage_access_footer: Cookie sẽ hết hạn sau 30 ngày.
|
22
|
-
request_storage_access_action: Tiếp tục
|
data/config/locales/zh-CN.yml
CHANGED
@@ -3,14 +3,3 @@ zh-CN:
|
|
3
3
|
logged_out: 已成功退出
|
4
4
|
could_not_log_in: 无法登录到 Shopify 商店
|
5
5
|
invalid_shop_url: 商店域名无效
|
6
|
-
enable_cookies_heading: 从 %{app} 启用 Cookie
|
7
|
-
enable_cookies_body: 您必须在此浏览器中手动启用 Cookie 才能在 Shopify 中使用 %{app}。
|
8
|
-
enable_cookies_footer: Cookie 使此应用能够通过暂时存储您的偏好设置和个人信息来验证您的身份。这些信息将在 30 天后过期。
|
9
|
-
enable_cookies_action: 启用 Cookie
|
10
|
-
top_level_interaction_heading: 您的浏览器需要对 %{app} 进行验证
|
11
|
-
top_level_interaction_body: 您的浏览器要求类似 %{app} 的应用向您申请访问 Cookie,之后 Shopify 才能为您打开它。
|
12
|
-
top_level_interaction_action: 继续
|
13
|
-
request_storage_access_heading: "%{app} 需要访问 Cookie"
|
14
|
-
request_storage_access_body: 这使此应用能够通过暂时存储您的个人信息来验证您的身份。点击继续并启用 Cookie 以使用此应用。
|
15
|
-
request_storage_access_footer: Cookie 将在 30 天后过期。
|
16
|
-
request_storage_access_action: 继续
|
data/config/locales/zh-TW.yml
CHANGED
@@ -3,14 +3,3 @@ zh-TW:
|
|
3
3
|
logged_out: 登出成功
|
4
4
|
could_not_log_in: 無法登入 Shopify 商店
|
5
5
|
invalid_shop_url: 商店網域無效
|
6
|
-
enable_cookies_heading: 啟用 %{app} 的 Cookie
|
7
|
-
enable_cookies_body: 您必須在此瀏覽器中手動啟用 Cookie,才能夠在 Shopify 使用 %{app}。
|
8
|
-
enable_cookies_footer: Cookie 可讓應用程式暫時儲存您的偏好設定和個人資訊,藉此驗證您的身分,這些資料會在 30 天後失效。
|
9
|
-
enable_cookies_action: 啟用 Cookie
|
10
|
-
top_level_interaction_heading: 您的瀏覽器需要驗證 %{app}
|
11
|
-
top_level_interaction_body: 您的瀏覽器要求 %{app} 等應用程式向您請求 Cookie 的存取權限,才能讓 Shopify 為您開啟該應用程式。
|
12
|
-
top_level_interaction_action: 繼續
|
13
|
-
request_storage_access_heading: "%{app} 需要 Cookie 存取權限"
|
14
|
-
request_storage_access_body: Cookie 可讓應用程式暫時儲存您的個人資訊,藉此驗證您的身分。按一下繼續並允許 Cookie 使用此應用程式。
|
15
|
-
request_storage_access_footer: Cookie 將於 30 天後失效。
|
16
|
-
request_storage_access_action: 繼續
|
data/config/routes.rb
CHANGED
@@ -8,6 +8,7 @@ ShopifyApp::Engine.routes.draw do
|
|
8
8
|
get login_url => :new, :as => :login
|
9
9
|
post login_url => :create, :as => :authenticate
|
10
10
|
get "logout" => :destroy, :as => :logout
|
11
|
+
get "patch_shopify_id_token" => :patch_shopify_id_token
|
11
12
|
|
12
13
|
# Kept to prevent apps relying on these routes from breaking
|
13
14
|
if login_url.gsub(%r{^/}, "") != "login"
|
@@ -26,6 +27,6 @@ ShopifyApp::Engine.routes.draw do
|
|
26
27
|
end
|
27
28
|
|
28
29
|
namespace :webhooks do
|
29
|
-
post ":type" => :receive
|
30
|
+
post "(:type)" => :receive
|
30
31
|
end
|
31
32
|
end
|
data/docs/Quickstart.md
CHANGED
@@ -34,8 +34,15 @@ HOST='https://some-random-words.trycloudflare.com/'
|
|
34
34
|
|
35
35
|
## Use Shopify App Bridge to embed your app in the Shopify Admin
|
36
36
|
|
37
|
-
A basic example of using [*Shopify App Bridge*](https://shopify.dev/tools/app-bridge) is included in the install generator. An instance Shopify App Bridge is automatically initialized in [shopify_app.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/shopify_app.js).
|
37
|
+
A basic example of using [*Shopify App Bridge*](https://shopify.dev/tools/app-bridge) is included in the install generator. An instance Shopify App Bridge is automatically initialized in [shopify_app.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/shopify_app.js).
|
38
38
|
|
39
|
-
|
39
|
+
If you are using the `shopify_app` gem **without** the [frontend react template](https://github.com/Shopify/shopify-frontend-template-react), the [flash_messages.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/flash_messages.js) file converts Rails [flash messages](https://api.rubyonrails.org/classes/ActionDispatch/Flash.html) to App Bridge Toast actions automatically. If your app is embedded and you want to display flash messages you will need to update the session storage to allow for 3rd party cookies. So that the flash messages can be save in the session cookie.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
#session_store.rb
|
43
|
+
Rails.application.config.session_store(:cookie_store, key: '_example_session', expire_after: 14.days, secure: true, same_site: 'None')
|
44
|
+
```
|
45
|
+
|
46
|
+
By default, this library is included via [unpkg in the embedded_app layout](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/embedded_app.html.erb#L27).
|
40
47
|
|
41
48
|
For more advanced uses it is recommended to [install App Bridge via npm or yarn](https://help.shopify.com/en/api/embedded-apps/app-bridge/getting-started#set-up-shopify-app-bridge-in-your-app).
|
data/docs/Troubleshooting.md
CHANGED
@@ -92,29 +92,6 @@ Edit `config/initializer/shopify_app.rb` and ensure the following configurations
|
|
92
92
|
+ config.shop_session_repository = 'Shop'
|
93
93
|
```
|
94
94
|
|
95
|
-
#### Inspect server logs
|
96
|
-
|
97
|
-
If you have checked the configurations above, and the app is still using cookies, then it is possible that the `shopify_app` gem defaulted to relying on cookies. This would happen when your browser allows third-party cookies and a session token was not successfully found as part of your request.
|
98
|
-
|
99
|
-
In this case, check the server logs to see if the session token was invalid:
|
100
|
-
|
101
|
-
```los
|
102
|
-
[ShopifyApp::JWT] Failed to validate JWT: [JWT::<Error>] <Failure message>
|
103
|
-
```
|
104
|
-
|
105
|
-
*Example*
|
106
|
-
|
107
|
-
```
|
108
|
-
[ShopifyApp::JWT] Failed to validate JWT: [JWT::ImmatureSignature] Signature nbf has not been reached
|
109
|
-
```
|
110
|
-
|
111
|
-
**Note:** In a local development environment, you may want to temporarily update your `Gemfile` to point to a local instance of the `shopify_app` library instad of an installed gem. This will enable you to use a debugging tool like `byebug` to debug the library.
|
112
|
-
|
113
|
-
```diff
|
114
|
-
- gem 'shopify_app', '~> 14.2'
|
115
|
-
+ gem 'shopify_app', path: '/path/to/shopify_app'
|
116
|
-
```
|
117
|
-
|
118
95
|
### My app can't make requests to the Shopify API
|
119
96
|
|
120
97
|
> **Note:** Session tokens cannot be used to make authenticated requests to the Shopify API. Learn more about authenticating your backend requests to Shopify APIs at [Shopify API authentication](https://shopify.dev/concepts/about-apis/authentication).
|
data/docs/Upgrading.md
CHANGED
@@ -8,6 +8,10 @@ This file documents important changes needed to upgrade your app's Shopify App v
|
|
8
8
|
|
9
9
|
[Unreleased](#unreleased)
|
10
10
|
|
11
|
+
[Upgrading to `v22.2.0`](#upgrading-to-v2220)
|
12
|
+
|
13
|
+
[Upgrading to `v22.0.0`](#upgrading-to-v2200)
|
14
|
+
|
11
15
|
[Upgrading to `v20.3.0`](#upgrading-to-v2030)
|
12
16
|
|
13
17
|
[Upgrading to `v20.2.0`](#upgrading-to-v2020)
|
@@ -38,8 +42,67 @@ We also recommend the use of a staging site which matches your production enviro
|
|
38
42
|
|
39
43
|
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)
|
40
44
|
|
45
|
+
## Unreleased
|
46
|
+
|
47
|
+
#### (v23.0.0) - Deprecated methods in CallbackController
|
48
|
+
The following methods from `ShopifyApp::CallbackController` have been deprecated in `v23.0.0`
|
49
|
+
- `perform_after_authenticate_job`
|
50
|
+
- `install_webhooks`
|
51
|
+
- `perform_post_authenticate_jobs`
|
52
|
+
|
53
|
+
If you have overwritten these methods in your callback controller to modify the behavior of the inherited `CallbackController`, you will need to
|
54
|
+
update your app to use configurable option `config.custom_post_authenticate_tasks` instead. See [post authenticate tasks](/docs/shopify_app/authentication.md#post-authenticate-tasks)
|
55
|
+
for more information.
|
56
|
+
|
57
|
+
#### (v23.0.0) - Removed `ShopifyApp::JWTMiddleware`
|
58
|
+
The `ShopifyApp::JWTMiddleware` middleware has been removed in `v23.0.0`. This middleware was used to populate the following environment variables from the JWT session token:
|
59
|
+
- `request.env["jwt.token"]`
|
60
|
+
- `request.env["jwt.shopify_domain"]`
|
61
|
+
- `request.env["jwt.shopify_user_id"]`
|
62
|
+
- `request.env["jwt.expire_at"]`
|
63
|
+
|
64
|
+
If you are using any of these variables in your app, you'll need to replace them. You can instead include the `ShopifyApp::WithShopifyIdToken` concern, which does the same JWT parsing as the middleware, and exposes the same values in the following helper methods:
|
65
|
+
- `shopify_id_token`
|
66
|
+
- `jwt_shopify_domain`
|
67
|
+
- `jwt_shopify_user_id`
|
68
|
+
- `jwt_expire_at`
|
69
|
+
|
70
|
+
#### (v23.0.0) - Deprecated "ShopifyApp::JWT" class
|
71
|
+
The `ShopifyApp::JWT` class has been deprecated in `v23.0.0`. Use [ShopifyAPI::Auth::JwtPayload](https://github.com/Shopify/shopify-api-ruby/blob/main/lib/shopify_api/auth/jwt_payload.rb)
|
72
|
+
class from the `shopify_api` gem instead. A search and replace should be enough for this migration.
|
73
|
+
- `ShopifyAPI::Auth::JwtPayload` is a superset of the `ShopifyApp::JWT` class, and contains methods that were available in `ShopifyApp::JWT`.
|
74
|
+
- `ShopifyAPI::Auth::JwtPayload` raises `ShopifyAPI::Errors::InvalidJwtTokenError` if the token is invalid.
|
75
|
+
|
76
|
+
## Upgrading to `v22.2.0`
|
77
|
+
#### Added new feature for zero redirect embedded app authorization flow - Token Exchange
|
78
|
+
A new embedded app authorization strategy has been introduced in `v22.2.0` that eliminates the redirects that were previously necessary for OAuth.
|
79
|
+
It can replace the existing installation and authorization code grant flow.
|
80
|
+
See [new embedded app authorization strategy](/README.md#new-embedded-app-authorization-strategy-token-exchange) for more information.
|
81
|
+
|
82
|
+
## Upgrading to `v22.0.0`
|
83
|
+
#### Dropped support for Ruby 2.x
|
84
|
+
Support for Ruby 2.x has been dropped as it is no longer supported. You'll need to upgrade to 3.x.x
|
85
|
+
|
86
|
+
#### Renamed Controller Concerns
|
87
|
+
The following controller concerns have been renamed/replaced in `v21.10.0` and have now been removed. To upgrade, please rename any usage in your apps's controllers that include them to the following:
|
88
|
+
|
89
|
+
|Old Deprecated Controller Concern |Replaced By New Controller Concern|
|
90
|
+
|---|---|
|
91
|
+
|`Authenticated`|`EnsureHasSession`|
|
92
|
+
|`RequireKnownShop`|`EnsureInstalled`|
|
93
|
+
|
94
|
+
The new names better reflect what assurances the including the controller concern provide. The new concern provide similar if not identical functionality as the concerns they replaced.
|
95
|
+
|
96
|
+
#### Remove ScripttagManager
|
97
|
+
Script tag usage has largely been replaced with the adoption of [theme app extensions](https://shopify.dev/docs/apps/online-store/theme-app-extensions) and [thank you order status customization](https://shopify.dev/docs/apps/checkout/thank-you-order-status). The manager has been removed with this major release due to effective replacement and a goal to have parity in supported functionality across language stacks.
|
98
|
+
|
99
|
+
If you find yourself still using Scipt Tags and want to continue the pattern of declarative management of script tags this gem used to use, we recommend porting the logic [the manager used in prior versions](https://github.com/Shopify/shopify_app/blob/2336fabc6d0b45a4dee3f336455dace4d2d88bc4/lib/shopify_app/managers/scripttags_manager.rb#L4) and implementing it in a [post authentication job](https://github.com/Shopify/shopify_app/blob/main/docs/shopify_app/authentication.md#run-jobs-after-the-oauth-flow). This is the recommended flow to create script tags (or any other logic) for stores that install your app.
|
100
|
+
|
101
|
+
#### No longer rescue non-shopify API errors during customized OAuth flow
|
102
|
+
If you have customized authentication logic and are counting on the `CallbackController` to catch your error and redirect to login, you'll need to catch that error and redirect to `login_url_with_optional_shop`.
|
103
|
+
|
41
104
|
## Upgrading to 21.3.0
|
42
|
-
The `Itp` controller concern has been removed from `LoginProtection` which is included by the `Authenticated` controller concern.
|
105
|
+
The `Itp` controller concern has been removed from `LoginProtection` which is included by the `Authenticated`/`EnsureHasSession` controller concern.
|
43
106
|
If any of your controllers are dependant on methods from `Itp` then you can include `ShopifyApp::Itp` directly.
|
44
107
|
You may notice a deprecation notice saying, `Itp will be removed in an upcoming version`.
|
45
108
|
This is because we intend on removing `Itp` completely in `v22.0.0`, but this will work in the meantime.
|
@@ -1,41 +1,184 @@
|
|
1
1
|
# Authentication
|
2
2
|
|
3
|
-
The Shopify App gem implements [OAuth 2.0](https://shopify.dev/tutorials/authenticate-with-oauth) to get [
|
3
|
+
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.
|
4
4
|
|
5
5
|
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.
|
6
6
|
|
7
|
-
See [*
|
7
|
+
See [*Getting started with session token authentication*](https://shopify.dev/docs/apps/auth/oauth/session-tokens/getting-started) to learn more.
|
8
8
|
|
9
9
|
> ⚠️ Be sure you understand the differences between the types of authentication schemes before reading this guide.
|
10
10
|
|
11
11
|
#### Table of contents
|
12
12
|
|
13
|
-
[OAuth
|
13
|
+
* [Supported types of OAuth Flow](#supported-types-of-oauth)
|
14
|
+
* [Token Exchange](#token-exchange)
|
15
|
+
* [Authorization Code Grant Flow](#authorization-code-grant-flow)
|
16
|
+
* [OAuth callback](#oauth-callback)
|
17
|
+
* [Customizing callback controller](#customizing-callback-controller)
|
18
|
+
* [Detecting scope changes](#detecting-scope-changes-1)
|
19
|
+
* [Run jobs after the OAuth flow](#post-authenticate-tasks)
|
20
|
+
* [Rotate API credentials](#rotate-api-credentials)
|
21
|
+
* [Making authenticated API requests after authorization](#making-authenticated-api-requests-after-authorization)
|
14
22
|
|
15
|
-
|
23
|
+
## Supported types of OAuth
|
24
|
+
> [!TIP]
|
25
|
+
> If you are building an embedded app, we **strongly** recommend using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
|
26
|
+
with [token exchange](#token-exchange) instead of the authorization code grant flow.
|
16
27
|
|
17
|
-
[
|
28
|
+
1. [Token Exchange](#token-exchange)
|
29
|
+
- Recommended and is only available for embedded apps
|
30
|
+
- Doesn't require redirects, which makes authorization faster and prevents flickering when loading the app
|
31
|
+
- Access scope changes are handled by Shopify when you use [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
|
32
|
+
2. [Authorization Code Grant Flow](#authorization-code-grant-flow)
|
33
|
+
- Suitable for non-embedded apps
|
34
|
+
- Installations, and access scope changes are managed by the app
|
18
35
|
|
19
|
-
|
20
|
-
* [`ShopifyApp::Authenticated`](#shopifyappauthenticated)
|
21
|
-
* [`ShopifyApp::EnsureAuthenticatedLinks`](#shopifyappensureauthenticatedlinks)
|
36
|
+
## Token Exchange
|
22
37
|
|
23
|
-
|
38
|
+
OAuth process by exchanging the current user's [session token (shopify id token)](https://shopify.dev/docs/apps/auth/session-tokens) for an
|
39
|
+
[access token](https://shopify.dev/docs/apps/auth/access-token-types/online.md) to make
|
40
|
+
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).
|
24
41
|
|
25
|
-
|
42
|
+
To enable token exchange authorization strategy, you can follow the steps in ["New embedded app authorization strategy"](/README.md#new-embedded-app-authorization-strategy).
|
43
|
+
Upon completion of the token exchange to get the access token, [post authenticated tasks](#post-authenticate-tasks) will be run.
|
26
44
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
* [Run jobs after the OAuth flow](#run-jobs-after-the-oauth-flow)
|
32
|
-
* Redirecting to the return address
|
45
|
+
Learn more about:
|
46
|
+
- [How token exchange works](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange)
|
47
|
+
- [Using Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
|
48
|
+
- [Configuring access scopes through the Shopify CLI](https://shopify.dev/docs/apps/tools/cli/configuration)
|
33
49
|
|
34
|
-
|
50
|
+
#### Handling invalid access tokens
|
51
|
+
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
|
52
|
+
the same operation.
|
53
|
+
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.
|
54
|
+
|
55
|
+
#### Detecting scope changes
|
56
|
+
|
57
|
+
##### Shopify managed installation
|
58
|
+
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.
|
59
|
+
Learn more about [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).
|
60
|
+
Using token exchange will ensure that the access token retrieved will always have the latest access scopes granted by the user.
|
61
|
+
|
62
|
+
## Authorization Code Grant Flow
|
63
|
+
Authorization code grant flow is the OAuth flow that requires the app to redirect the user
|
64
|
+
to Shopify for installation/authorization of the app to access the shop's data. It is still required for apps that are not embedded.
|
65
|
+
|
66
|
+
If your app is not using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation) with declared scopes in your `.toml` file, you can change the requested access scopes during OAuth flow
|
67
|
+
by adding the `scope` to your configurations - `ShopifyApp.configuration` & `ShopifyAPI::Context.setup`.
|
68
|
+
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
# config/initializers/shopify_app.rb
|
72
|
+
|
73
|
+
ShopifyApp.configure do |config|
|
74
|
+
...
|
75
|
+
config.scope = ["read_discounts", "write_products"]
|
76
|
+
...
|
77
|
+
end
|
78
|
+
|
79
|
+
ShopifyAPI::Context.setup(
|
80
|
+
...
|
81
|
+
scope: ShopifyApp.configuration.scope,
|
82
|
+
...
|
83
|
+
)
|
84
|
+
```
|
85
|
+
|
86
|
+
To perform [authorization code grant flow](https://shopify.dev/docs/apps/auth/get-access-tokens/authorization-code-grant), you app will need to handle
|
87
|
+
[begin OAuth](#begin-oauth) and [OAuth callback](#oauth-callback) routes.
|
88
|
+
|
89
|
+
### Begin OAuth
|
90
|
+
ShopifyApp automatically redirects the user to Shopify to complete OAuth to install the app when the `ShopifyApp.configuration.login_url` is reached.
|
91
|
+
Behind the scenes the ShopifyApp gem starts the process by calling `ShopifyAPI::Auth::Oauth.begin_auth` to build the
|
92
|
+
redirect URL with necessary parameters like the OAuth callback URL, scopes requested, type of access token (offline or online) requested, etc.
|
93
|
+
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)
|
94
|
+
for detailed implementation)
|
95
|
+
|
96
|
+
### OAuth callback
|
97
|
+
|
98
|
+
Shopify will redirect the merchant back to your app's callback URL once they approve the app installation.
|
99
|
+
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)
|
100
|
+
|
101
|
+
The default callback controller [`ShopifyApp::CallbackController`](../../app/controllers/shopify_app/callback_controller.rb) provides the following behaviour:
|
102
|
+
|
103
|
+
1. Logging into the shop and resetting the session
|
104
|
+
2. Storing the session to the `SessionRepository`
|
105
|
+
3. [Post authenticate tasks](#post-authenticate-tasks)
|
106
|
+
4. Redirecting to the return address
|
107
|
+
|
108
|
+
#### Customizing callback controller
|
109
|
+
If you need to define a custom callback controller to handle your app's use case, you can configure the callback route to your controller.
|
110
|
+
|
111
|
+
Example:
|
112
|
+
|
113
|
+
1. Create the new custom callback controller
|
114
|
+
```ruby
|
115
|
+
# web/app/controllers/my_custom_callback_controller.rb
|
116
|
+
|
117
|
+
class MyCustomCallbackController
|
118
|
+
def callback
|
119
|
+
# My custom callback logic
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
2. Override callback routing to this controller
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
# web/config/routes.rb
|
128
|
+
|
129
|
+
Rails.application.routes.draw do
|
130
|
+
root to: "home#index"
|
131
|
+
|
132
|
+
# Overriding the callback controller to the new custom one.
|
133
|
+
# This must be added before mounting the ShopifyApp::Engine
|
134
|
+
get ShopifyApp.configuration.login_callback_url, to: 'my_custom_callback#callback'
|
135
|
+
|
136
|
+
mount ShopifyApp::Engine, at: "/api"
|
137
|
+
|
138
|
+
# other routes
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
142
|
+
### Detecting scope changes
|
143
|
+
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.
|
144
|
+
|
145
|
+
When an app's access scopes change, it needs to request merchants to go through OAuth again to renew its permissions.
|
146
|
+
|
147
|
+
See [Handling changes in access scopes](/docs/shopify_app/handling-access-scopes-changes.md).
|
148
|
+
|
149
|
+
## Post Authenticate tasks
|
150
|
+
After authentication is complete, a few tasks are run by default by PostAuthenticateTasks:
|
151
|
+
1. [Installing Webhooks](/docs/shopify_app/webhooks.md)
|
152
|
+
2. [Run configured after_authenticate_job](#after_authenticate_job)
|
153
|
+
|
154
|
+
The [PostAuthenticateTasks](https://github.com/Shopify/shopify_app/blob/main/lib/shopify_app/auth/post_authenticate_tasks.rb)
|
155
|
+
class is responsible for triggering the webhooks manager for webhooks registration, and enqueue jobs from [after_authenticate_job](#after_authenticate_job).
|
156
|
+
|
157
|
+
If you simply need to enqueue more jobs to run after authenticate, use [after_authenticate_job](#after_authenticate_job) to define these jobs.
|
158
|
+
|
159
|
+
If your post authentication tasks is more complex and is different than just installing webhooks and enqueuing jobs,
|
160
|
+
you can customize the post authenticate tasks by creating a new class that has a `self.perform(session)` method,
|
161
|
+
and configuring `custom_post_authenticate_tasks` in the initializer.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
# my_custom_post_authenticate_task.rb
|
165
|
+
class MyCustomPostAuthenticateTask
|
166
|
+
def self.perform(session)
|
167
|
+
# This will be triggered after OAuth callback and token exchange completion
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# config/initializers/shopify_app.rb
|
172
|
+
ShopifyApp.configure do |config|
|
173
|
+
config.custom_post_authenticate_tasks = "MyCustomPostAuthenticateTask"
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+
#### after_authenticate_job
|
35
178
|
|
36
179
|
See [`ShopifyApp::AfterAuthenticateJob`](/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb).
|
37
180
|
|
38
|
-
If your app needs to perform specific actions after the user is authenticated successfully (i.e. every time a new session is created), ShopifyApp can queue or run a job of your choosing
|
181
|
+
If your app needs to perform specific actions after the user is authenticated successfully (i.e. every time a new session is created), ShopifyApp can queue or run a job of your choosing. To configure the after authenticate job, update your initializer as follows:
|
39
182
|
|
40
183
|
```ruby
|
41
184
|
ShopifyApp.configure do |config|
|
@@ -49,7 +192,7 @@ If you need the job to run synchronously add the `inline` flag:
|
|
49
192
|
|
50
193
|
```ruby
|
51
194
|
ShopifyApp.configure do |config|
|
52
|
-
config.after_authenticate_job = { job: Shopify::AfterAuthenticateJob, inline: true }
|
195
|
+
config.after_authenticate_job = { job: "Shopify::AfterAuthenticateJob", inline: true }
|
53
196
|
end
|
54
197
|
```
|
55
198
|
|
@@ -63,7 +206,7 @@ If you want to perform that action only once, e.g. send a welcome email to the u
|
|
63
206
|
|
64
207
|
## Rotate API credentials
|
65
208
|
|
66
|
-
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).
|
209
|
+
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).
|
67
210
|
|
68
211
|
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:
|
69
212
|
|
@@ -72,6 +215,17 @@ config.secret = Rails.application.secrets.shopify_secret
|
|
72
215
|
config.old_secret = Rails.application.secrets.old_shopify_secret
|
73
216
|
```
|
74
217
|
|
218
|
+
Also make sure the old secret is specified when setting up `ShopifyAPI::Context` as well:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
ShopifyAPI::Context.setup(
|
222
|
+
api_key: ShopifyApp.configuration.api_key,
|
223
|
+
api_secret_key: ShopifyApp.configuration.secret,
|
224
|
+
# ...
|
225
|
+
old_api_secret_key: ShopifyApp.configuration.old_secret,
|
226
|
+
)
|
227
|
+
```
|
228
|
+
|
75
229
|
We've provided a generator which creates the job and an example rake task:
|
76
230
|
|
77
231
|
```sh
|
@@ -86,43 +240,10 @@ strategy.options[:old_client_secret] = ShopifyApp.configuration.old_secret
|
|
86
240
|
|
87
241
|
> **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`:
|
88
242
|
|
89
|
-
##
|
243
|
+
## Making authenticated API requests after authorization
|
244
|
+
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.
|
90
245
|
|
91
|
-
|
92
|
-
|
93
|
-
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.
|
94
|
-
|
95
|
-
*Example:*
|
96
|
-
|
97
|
-
```rb
|
98
|
-
class AuthenticatedController < ApplicationController
|
99
|
-
include ShopifyApp::Authenticated
|
100
|
-
end
|
101
|
-
|
102
|
-
class ApiController < AuthenticatedController
|
103
|
-
# Actions in this controller are protected
|
104
|
-
end
|
105
|
-
```
|
106
|
-
|
107
|
-
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`.
|
108
|
-
|
109
|
-
#### Embedded apps and `ShopifyApp::Authenticated`
|
110
|
-
|
111
|
-
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).
|
112
|
-
|
113
|
-
### `ShopifyApp::EnsureAuthenticatedLinks`
|
114
|
-
|
115
|
-
The [`ShopifyApp::EnsureAuthenticatedLinks`](/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb) concern helps authenticate users that access protected pages of your app directly.
|
116
|
-
|
117
|
-
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.
|
118
|
-
|
119
|
-
*Example:*
|
120
|
-
|
121
|
-
```rb
|
122
|
-
class AuthenticatedController < ApplicationController
|
123
|
-
include ShopifyApp::EnsureAuthenticatedLinks
|
124
|
-
include ShopifyApp::Authenticated
|
125
|
-
end
|
126
|
-
```
|
246
|
+
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.
|
127
247
|
|
128
|
-
|
248
|
+
- ⚠️ See [Sessions](./sessions.md) page to understand how sessions work.
|
249
|
+
- ⚠️ See [Controller Concerns](./controller-concerns.md) page to understand when to use which concern.
|