Module: ShopifyApp::LoginProtection

Extended by:
ActiveSupport::Concern
Includes:
SanitizedParams
Included in:
CallbackController, SessionsController
Defined in:
lib/shopify_app/controller_concerns/login_protection.rb

Constant Summary collapse

ACCESS_TOKEN_REQUIRED_HEADER =
"X-Shopify-API-Request-Failure-Unauthorized"

Instance Method Summary collapse

Instance Method Details

#activate_shopify_sessionObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/shopify_app/controller_concerns/login_protection.rb', line 26

def activate_shopify_session
  if current_shopify_session.blank?
    signal_access_token_required
    ShopifyApp::Logger.debug("No session found, redirecting to login")
    return 
  end

  if ShopifyApp.configuration.reauth_on_access_scope_changes &&
      !ShopifyApp.configuration.user_access_scopes_strategy.covers_scopes?(current_shopify_session)
    clear_shopify_session
    return 
  end

  begin
    ShopifyApp::Logger.debug("Activating Shopify session")
    ShopifyAPI::Context.activate_session(current_shopify_session)
    yield
  ensure
    ShopifyApp::Logger.debug("Deactivating session")
    ShopifyAPI::Context.deactivate_session
  end
end

#add_top_level_redirection_headers(url: nil, ignore_response_code: false) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/shopify_app/controller_concerns/login_protection.rb', line 85

def add_top_level_redirection_headers(url: nil, ignore_response_code: false)
  if request.xhr? && (ignore_response_code || response.code.to_i == 401)
    ShopifyApp::Logger.debug("Adding top level redirection headers")
    # Make sure the shop is set in the redirection URL
    unless params[:shop]
      ShopifyApp::Logger.debug("Setting current shop session")
      params[:shop] = if current_shopify_session
        current_shopify_session.shop

      elsif (matches = request.headers["HTTP_AUTHORIZATION"]&.match(/^Bearer (.+)$/))
        jwt_payload = ShopifyAPI::Auth::JwtPayload.new(T.must(matches[1]))
        jwt_payload.shop
      end
    end

    url ||= 

    ShopifyApp::Logger.debug("Setting Reauthorize-Url to #{url}")
    response.set_header("X-Shopify-API-Request-Failure-Reauthorize", "1")
    response.set_header("X-Shopify-API-Request-Failure-Reauthorize-Url", url)
  end
end

#current_shopify_sessionObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/shopify_app/controller_concerns/login_protection.rb', line 49

def current_shopify_session
  @current_shopify_session ||= begin
    cookie_name = ShopifyAPI::Auth::Oauth::SessionCookie::SESSION_COOKIE_NAME
    load_current_session(
      auth_header: request.headers["HTTP_AUTHORIZATION"],
      cookies: { cookie_name => cookies.encrypted[cookie_name] },
      is_online: online_token_configured?,
    )
  rescue ShopifyAPI::Errors::CookieNotFoundError
    ShopifyApp::Logger.warn("No cookies have been found - cookie name: #{cookie_name}")
    nil
  rescue ShopifyAPI::Errors::InvalidJwtTokenError
    ShopifyApp::Logger.warn("Invalid JWT token for current Shopify session")
    nil
  end
end

#jwt_expire_atObject



78
79
80
81
82
83
# File 'lib/shopify_app/controller_concerns/login_protection.rb', line 78

def jwt_expire_at
  expire_at = request.env["jwt.expire_at"]
  return unless expire_at

  expire_at - 5.seconds # 5s gap to start fetching new token in advance
end

#login_again_if_different_user_or_shopObject



66
67
68
69
70
71
72
# File 'lib/shopify_app/controller_concerns/login_protection.rb', line 66

def 
  return unless session_id_conflicts_with_params || session_shop_conflicts_with_params

  ShopifyApp::Logger.debug("Clearing session and redirecting to login")
  clear_shopify_session
  
end

#signal_access_token_requiredObject



74
75
76
# File 'lib/shopify_app/controller_concerns/login_protection.rb', line 74

def signal_access_token_required
  response.set_header(ACCESS_TOKEN_REQUIRED_HEADER, "true")
end