Go back to the main page

Bare-bones QuickBooks Single Sign On with Rails

 

 


Fundamental Rails/QuickBooks Single Sign On (SSO)

In my previous tutorial I went over implementing SSO with Rails and Devise. This tutorial will focus on a basic implementation featuring just Rails (4.1.6) with subdomains

  1. Fire up a new rails app
  2. $ rails new intuit_sso -T
    $ cd intuit_sso
    
  3. Add these to the Gemfile next
  4. gem "omniauth", ">= 1.0.3"
    gem 'omniauth-openid'
    
      bundle install
    
  5. The config/initializers/omniauth.rb should look like this.
  6. Rails.application.config.middleware.use OmniAuth::Builder do
      provider :open_id, :name => 'intuit', :identifier => 'https://openid.intuit.com/openid/xrds'
    end
    
  7. While in the initializers edit the config/initializers/cookies_serializer.rb
  8. Rails.application.config.action_dispatch.cookies_serializer = :marshal
    
    Minimul says —

    It seems one of the core underlying gems, ruby-openid, is not playing nicely with the Rails 4.1 default of Rails.application.config.action_dispatch.cookies_serializer = :json

  9. Make a Login controller with 2 actions, index and callback.
  10. $ bin/rails g controller Login index callback
      
    
  11. In app/views/login/index.html.erb put the Intuit SSO button.
  12. <h1>Login#index</h1>
    <ipp:login href="/auth/intuit" type="horizontal"></ipp:login>
    <script type="text/javascript" src="https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js"></script>
    
  13. Add these routes.
  14.   
    match '/auth/:provider/callback' => 'login#callback', via: [:get, :post]
    root 'login#index', :constraints => { :subdomain => /.+/ }
    
    Minimul says —

    Just a reminder: Make sure you add both :get and :post for the callback.

  15. Before we start working on the callback let's make a user.
  16.   $ bin/rails g model User email password
    
  17. The app/models/user.rb should look like this:
  18. class User < ActiveRecord::Base
    
      def self.find_for_open_id(access_token)
        data = access_token.info
        if user = User.where(:email => data["email"]).first
          user
        else
          User.create!(email: data["email"], password: generate_token)
        end
      end
    
      def self.generate_token
        Digest::SHA1.hexdigest("#{Rails.application.config.secret_token}#{Time.now.to_i}")
      end
    
    end
    
  19. Now we can implement the callback action within app/controllers/login_controller.rb as so:
  20.   
    class LoginController < ApplicationController
      skip_before_filter :verify_authenticity_token, :only => [:callback]
    
      def index
      end
    
      def callback
        if user = User.find_for_open_id(request.env["omniauth.auth"])
          session[:user_id] = user.id
          redirect_to start_index_url
        else
          redirect_to root_url, notice: 'Auth fail'
        end
      end
    end
    
    Minimul says —

    If you like to spin your wheels a bit and waste an hour or so go ahead and NOT skip the verify_authenticity_token.

  21. You may have noticed a redirect to a non-existent route and controller, start_index_url, so let's implement that now.
  22. $ bin/rails g controller Start index 
    
  23. In conjunction, let's fill in the route, controller, and view for this start redirect.
  24.   # config/routes.rb
      get 'start/index', :constraints => { :subdomain => /.+/ }
    
    # app/controllers/start_controller.rb
    class StartController < ApplicationController
      def index
        @current_user = User.find(session[:user_id])
      end
    end
    
    
    <h1>Start#index</h1>
    <h2><%= "Welcome #{@current_user.email}" %></h2>
    <p>Find me in app/views/start/index.html.erb</p>
    
  25. Now we are ready to test.
  26. $ bin/rails s
    
    Pump in a subdomain with lvh.me:3000 and click "Sign in with Intuit".
    Fill in your QBO creds.
    Successful sign on.

That concludes the tutorial for Bare-bones QuickBooks Single Sign On with Rails

Be sure to check out the screencast for more commentary as well as the code. For feedback use the comments area below rather than my email. If the question is broader than this tutorial use the Intuit Developer Forums, in which I regularly hang out.