Devise + OmniAuth + Facebook (what happens there)

I was curious what’s happening under the hood when facebook authentication is enabled. I specified some breakpoints in my RubyMine to find out in which order the particular methods are called.

The integration of Facebook consists of these steps: (for more information read https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview):

  • adding some gems to Gemfile:

    #facebook integration
    gem 'omniauth'
    gem 'omniauth-facebook'
    gem 'omniauth-twitter'
    gem 'omniauth-linkedin'
    
  • Adding new columns to the table:

    bundle install
    rails g migration AddColumnsToUsers provider uid #note: name is already there
    rake db:migrate
    
  • make the new columns accessible (for mass assignment):

    # User model
    attr_accessible :provider, :uid
    
  • extending config by adding the facebook configuration:

    # initializers/devise.rb:
    # require the gem and add it to the config!
    
      require "omniauth-facebook"
      config.omniauth :facebook, "5745245454154", "5ecd0a644303fab5c19dfdfdf383d06", #your APP_ID and APP_SECRET
                      #for heroku necessary (development env. works as well)
                      {:strategy_class => OmniAuth::Strategies::Facebook,
                       :scope => 'email, offline_access',
                       :client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}}}
    
  • user model must have to class instance methods (see link above):

    
    #### User model must have:
    
    find_for_facebook_oauth
    find_in_session
    
  • User model must make itself “omniauthable”:

    devise : omniauthable, : omniauth_providers => [:facebook]
    
  • we need an additional controller for handling authentication provider method (facebook, twitter, …)

    #### Users controller must have a "sub controller":
    Users::OmniauthCallbacksController with facebook method.
    
  • we actually don’t need to add a link any view. The links are rendered automatically in this partial:

    /devise/shared/_links.html.erb partial
    
  • routes.rb file must be updated accordingly:

      devise_for :users, :controllers => { : omniauth_callbacks => "users/omniauth_callbacks" }
      resources :users
    

When everything is in place I can start a short debug session just to understand what’s going on and where RoR will step in.

facebook_devise_integration_sequence

I think the content of the image is self-explanatory. Devise maps the particular URLs to the actions in the controllers this way:

                    root          /                                      home#index
                    root          /                                      home#index
        new_user_session GET      /users/sign_in(.:format)               devise/sessions#new
            user_session POST     /users/sign_in(.:format)               devise/sessions#create
    destroy_user_session DELETE   /users/sign_out(.:format)              devise/sessions#destroy
           user_password POST     /users/password(.:format)              devise/passwords#create
       new_user_password GET      /users/password/new(.:format)          devise/passwords#new
      edit_user_password GET      /users/password/edit(.:format)         devise/passwords#edit
                         PUT      /users/password(.:format)              devise/passwords#update
cancel_user_registration GET      /users/cancel(.:format)                devise/registrations#cancel
       user_registration POST     /users(.:format)                       devise/registrations#create
   new_user_registration GET      /users/sign_up(.:format)               devise/registrations#new
  edit_user_registration GET      /users/edit(.:format)                  devise/registrations#edit
                         PUT      /users(.:format)                       devise/registrations#update
                         DELETE   /users(.:format)                       devise/registrations#destroy
 user_omniauth_authorize GET|POST /users/auth/:provider(.:format)        users/omniauth_callbacks#passthru {:provider=>/facebook/}
  user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) users/omniauth_callbacks#(?-mix:facebook)
                   users GET      /users(.:format)                       users#index
                         POST     /users(.:format)                       users#create
                new_user GET      /users/new(.:format)                   users#new
               edit_user GET      /users/:id/edit(.:format)              users#edit
                    user GET      /users/:id(.:format)                   users#show
                         PUT      /users/:id(.:format)                   users#update
                         DELETE   /users/:id(.:format)                   users#destroy

HTML5 / Producer-consumer-problem solved with WebWorkers

HTML5 provides the mechanism called “WebWorkers”. This feature is very nice and you can learn more about it here: http://www.html5rocks.com/en/tutorials/workers/basics/. There is also a new feature called “MessageChannel” which is meant to be used for the communication among the different origins (http://somedomain and https://somedomain:8080). I think this article is useful to learn more about it: http://www.webgranth.com/html5-web-messaging-fresh-tutorial-for-cross-document-messaging.

This post is going to create two WebWorkers and let them communicate with each other through a MessageChannel. Moreover, the WebWorkers implement the Producer-consumer-problem. The WebWorker #1 is the producer. It generates Fibonacci numbers and posts the result to the WebWorker #2. The WebWorker #2 receives the numbers and removes some of them. When it’s done with the work it posts the result back to the WebWorker #1. The WebWorker #1 fills some numbers again and posts them back to the WebWorker #2 and so on…

See it in action here: http://producer-consumer-webworker.herokuapp.com/index.html

Fork it on GitHub: https://github.com/jepetko/webworker

Continue reading

JetBrains WebStorm/PHPStorm + jQuery + JsTestDriver + Jasmine

This post describes a workaround to get the triple jQuery + JsTestDriver + Jasmine working inside JetBrains WebStorm to be able to perform tests from the IDE.

As mentioned in this post http://blog.jetbrains.com/webide/2011/10/javascript-unit-testing-support/#comment-6600 there are apparently some issue when you try to run the built-in version of the JsUnitDriver. The result is the following exception that is thrown when you try to capture the browser:

Continue reading

Javascript / Inheriting the “DNA” vs. mixing behaviour

The inheritance approaches in Javascript are discussed quite often. The most people, especially Java developer (me too?), have troubles with proper usage of the inheritance.

There are 3 approaches:

  • prototypical inheritance: this is actually the javascript way
  • functional inheritance: is about mixing objects into other objects
  • classical inheritance: IMHO, this approach doesn’t exist. It can be simulated but it’s not real.

Continue reading