Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create concern to authenticate deep links using Turbolinks #1118

Merged
merged 3 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,21 @@ The engine provides a `ShopifyApp::Authenticated` concern which should be includ

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`.

### EnsureAuthenticatedLinks

The `ShopifyApp::EnsureAuthenticatedLinks` 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://shopify.dev/tutorials/authenticate-server-side-rendered-apps-with-session-tokens-app-bridge-turbolinks). It adds a `before_action` filter that detects whether a session token is present or not. If a session is not found, the user is redirected to your app's splash page path (`root_path`) along with `return_to` and `shop` parameters.

Example `AuthenticatedController`:

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

### AfterAuthenticate Job

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 (note that we already provide support for automatically creating Webhooks and Scripttags). To configure the after authenticate job, update your initializer as follows:
Expand Down
22 changes: 22 additions & 0 deletions app/controllers/concerns/shopify_app/ensure_authenticated_links.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module ShopifyApp
module EnsureAuthenticatedLinks
extend ActiveSupport::Concern

included do
before_action :redirect_to_splash_page, if: :missing_expected_jwt?
end

private

def redirect_to_splash_page
splash_page_path = root_path(return_to: request.fullpath, shop: current_shopify_domain)
redirect_to(splash_page_path)
end

def missing_expected_jwt?
jwt_shopify_domain.blank?
end
end
end
58 changes: 58 additions & 0 deletions test/controllers/concerns/ensure_authenticated_links_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# frozen_string_literal: true

require 'test_helper'

class EnsureAuthenticatedLinksTest < ActionController::TestCase
class TurbolinksTestController < ActionController::Base
include ShopifyApp::EnsureAuthenticatedLinks

def root
render(html: '<h1>Splash Page</ h1>')
end

def some_link
render(html: '<h1>Success</ h1>')
end

private

def jwt_shopify_domain
request.env['jwt.shopify_domain']
end

def current_shopify_domain
'test-shop.myshopify.com'
end
end

tests TurbolinksTestController

setup do
@shop_domain = 'test-shop.myshopify.com'

Rails.application.routes.draw do
root to: 'ensure_authenticated_links_test/turbolinks_test#root'
get '/some_link', to: 'ensure_authenticated_links_test/turbolinks_test#some_link'
end
end

teardown do
Rails.application.reload_routes!
end

test 'redirects to splash page with a return_to and shop param if no session token is present' do
get :some_link, params: { shop: @shop_domain }

expected_path = root_path(return_to: request.fullpath, shop: @shop_domain)

assert_redirected_to expected_path
end

test 'returns the requested resource if a valid session token exists' do
request.env['jwt.shopify_domain'] = @shop_domain

get :some_link, params: { shop: @shop_domain }

assert_response :ok
end
end