module ShopifyAPI::Auth::Oauth
Constants
- NONCE_LENGTH
Public Class Methods
Source
# File lib/shopify_api/auth/oauth.rb, line 22 def begin_auth(shop:, redirect_path:, is_online: true, scope_override: nil) scope = if scope_override.nil? ShopifyAPI::Context.scope elsif scope_override.is_a?(ShopifyAPI::Auth::AuthScopes) scope_override else ShopifyAPI::Auth::AuthScopes.new(scope_override) end unless Context.setup? raise Errors::ContextNotSetupError, "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup" end raise Errors::UnsupportedOauthError, "Cannot perform OAuth for private apps." if Context.private? state = SecureRandom.alphanumeric(NONCE_LENGTH) cookie = SessionCookie.new(value: state, expires: Time.now + 60) query = { client_id: ShopifyAPI::Context.api_key, scope: scope.to_s, redirect_uri: "#{ShopifyAPI::Context.host}#{redirect_path}", state: state, "grant_options[]": is_online ? "per-user" : "", } query_string = URI.encode_www_form(query) auth_route = auth_base_uri(shop) + "/oauth/authorize?#{query_string}" { auth_route: auth_route, cookie: cookie } end
Source
# File lib/shopify_api/auth/oauth.rb, line 60 def validate_auth_callback(cookies:, auth_query:) unless Context.setup? raise Errors::ContextNotSetupError, "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup" end raise Errors::InvalidOauthError, "Invalid OAuth callback." unless Utils::HmacValidator.validate(auth_query) raise Errors::UnsupportedOauthError, "Cannot perform OAuth for private apps." if Context.private? state = cookies[SessionCookie::SESSION_COOKIE_NAME] raise Errors::NoSessionCookieError unless state raise Errors::InvalidOauthError, "Invalid state in OAuth callback." unless state == auth_query.state null_session = Auth::Session.new(shop: auth_query.shop) body = { client_id: Context.api_key, client_secret: Context.api_secret_key, code: auth_query.code } client = Clients::HttpClient.new(session: null_session, base_path: "/admin/oauth") response = begin client.request( Clients::HttpRequest.new( http_method: :post, path: "access_token", body: body, body_type: "application/json", ), ) rescue ShopifyAPI::Errors::HttpResponseError => e raise Errors::RequestAccessTokenError, "Cannot complete OAuth process. Received a #{e.code} error while requesting access token." end session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h session = Session.from(shop: auth_query.shop, access_token_response: Oauth::AccessTokenResponse.from_hash(session_params)) cookie = if Context.embedded? SessionCookie.new( value: "", expires: Time.now, ) else SessionCookie.new( value: session.id, expires: session.online? ? session.expires : nil, ) end { session: session, cookie: cookie } end
Private Class Methods
Source
# File lib/shopify_api/auth/oauth.rb, line 113 def auth_base_uri(shop) return "https://#{shop}/admin" unless defined?(DevServer) && shop.include?(".my.shop.dev") # For first-party apps in development only, we leverage DevServer to build the admin base URI admin_web = T.unsafe(Object.const_get("DevServer")).new("web") # rubocop:disable Sorbet/ConstantsFromStrings admin_host = admin_web.host!(nonstandard_host_prefix: "admin") shop_name = shop.split(".").first "https://#{admin_host}/store/#{shop_name}" end