Authentication with the external application


Using OmniAuth2

OAuth 2 is an authorization protocol that enables a third-party applications to obtain limited access to an HTTP service. One of the main aspects of this protocol is the access token that is issued to the application. This token is used by the app to perform various actions on the user’s behalf. However, it can’t perform something that was not approved (for example, the user may only allow an app to fetch information about contacts, but not orders or products).


The connector framework provides a template controller to implement the OmniAuth2 (Web Server) authentication cycle. Three actions are provided:


  • request_omniauth. The main purpose of this action is to send the request to YourApplication website to retrieve a unique code that will be exchanged for a token. A typical implementation, using the Omniauth gem (Your application might provide a specific gem), would look like this:

    request_omniauth
    def request_omniauth
        return redirect_to root_url unless is_admin
        
        # Retrieve the uid of your organization
        org_uid = params[:org_uid]
        # This parameter is specific to Shopify
        shop_name = params[:shop]
        if shop_name.blank?
          flash[:error] = 'My shopify store url is required'
          return redirect_to root_url
        end
        shop = shop_name.strip + '.myshopify.com'
    
        auth_params = {
            # Include the state in your request
            :state => current_organization.uid,
            :shop => shop
        }
        # Make sure to provide a sanitised URL
        auth_params = URI.escape(auth_params.collect { |k, v| "#{k}=#{v}" }.join('&'))
      
      # Request the code using the Omniauth gem implementation
      redirect_to "/auth/#{params[:provider]}?#{auth_params}", id: 'sign_in'
    end
  • create_omniauth. This action consumes the callback received from the authorization server and updates current_organization with the credentials. A typical implementation would look like this:

    create_omniauth
    def create_omniauth
      omniauth_params = request.env['omniauth.params']
      org_uid = omniauth_params['state'] if omniauth_params
      response = request.env['omniauth.auth']
    
      return redirect_to root_url unless is_admin && org_uid && response
      
      # This parameter is specific to Shopify, and can be any unique identifier sent by YourApplication
      shop_name = response.uid
      # This method is provided by the framework and expects data with specific fields. Find more information in the FAQ section. 
    
      current_organization.from_omniauth(response)
    
      current_organization.instance_url = "https://#{shop_name}/admin"
    
      unless current_organization.save
        flash[:alert] = "Oops, your account could not be linked. #{format_errors(current_organization)}"
        return redirect_to root_url
      end
      
      # Webhooks implementation is application specific
      token = response['credentials']['token']
      Shopify::Webhooks::WebhooksManager.queue_create_webhooks(org_uid, shop_name, token)
    
      redirect_to root_url
    rescue => e
      Maestrano::Connector::Rails::ConnectorLogger.log('warn', current_organization, "An error has occurred in the auth process: #{e}")
      return redirect_to root_url
    end
    
  • destroy_omniauth. This action takes care of clearing the information from your {{current-organization}}:
    destroy_omniauth
    def destroy_omniauth
      return redirect_to root_url unless is_admin
      
      current_organization.clear_omniauth
    
      redirect_to root_url
    end