Domain and subdomain routing in rails

02.19.2010

I needed to be able to route any domain that was not my own to a single controller.  And furthermore I had to route any subdomain that was not ” and not ‘www’ to that same controller.

If you can’t guess why, it is because it is a hosted application.  In any case, I used the request_routing plugin and it seemed OK for my needs.  The problem was, it didn’t accept things like :not => ‘www’ or :not => ”.  So, I ended up using a regular expression for my result.  Here goes.

  1.  not_domain_regex = Regexp.new(\A(?!(’ + AConfig::domain.gsub(‘.’, \.) + ‘))’, true)
  2.   is_domain_regex = Regexp.new(\A((’ + AConfig::domain.gsub(‘.’, \.) + ‘))’, true)
  3.   map.connect(
  4.     ‘*path’,
  5.     :controller => ‘external’,
  6.     :action => ‘handler’,
  7.     :conditions => {
  8.       :domain => not_domain_regex
  9.     }
  10.   )
  11.   map.connect(
  12.     ‘*path’,
  13.     :controller => ‘external’,
  14.     :action => ‘handler’,
  15.     :conditions => {
  16.       :domain  => is_domain_regex,
  17.       :subdomain => /([a-z0-9\-\_]{1,100}[^www])/i
  18.     }
  19.   )

The next step in this will be to replace “*path” with “:controller/:action/:id” and have it route to namespaced controllers.

Ex:

/controllers/external/controller_name.rb

If you have any ideas on that part.  Let me know :)

Cross domain sessions

02.18.2010

I have been racking my brain for some time on how to accomplish cross domain sessions.  It was especially puzzling at first since the application I was working on ran multiple sites.  So, the code base was the same, even though the domain might change.

I will not go too deep into security on this, I am just going to give you the tools to explore the concept.

The first step you will have to take is to create a services file on the original site providing the session, in this case I will be using rails.

  1. #Controller
  2. class ServiceController < ApplicationController
  3.   def sessioninfo
  4.     if session[:user]
  5.       @referrer = ‘var referrer=\’ + request.env[‘HTTP_REFERER’].to_s + \’;’
  6.       @user = ‘var user=’ + session[:user].to_json + ‘;’
  7.     else
  8.       #there was no session
  9.     end
  10.   end
  11. end

What ultimately gets outputted from this is the following:

  1. #output
  2. var referrer=‘http://www.thereferrer.com’;
  3. var user={"user"{"username":"joshmattvander"}}

Now the session is ultimately exposed on the original site.  But we need to get it from another site.  The only way to accomplish that I can find is to use javascript.  What you are going to do is add a script to the head of the document with your exposed service URL in my case (http://mysite.com/service/sessioninfo).  The reason we are doing this in javascript, is because if we did this on the server side, the session would be blank.  By doing this in javascript it is as if the user was returning to the URL themselves so the session is still alive and kicking.

  1.  
  2. $(document).ready(function(){
  3.         var scriptEl = $(‘<script type="text/javascript" src="http://mysite.com/service/sessioninfo"></script>’);
  4.         $(scriptEl).appendTo($(‘head’));
  5.         setTimeout(function(){
  6.                 try {
  7.                         if (referrer && user) {
  8.                         alert(‘The referring site is: ‘ + referrer + ‘.’)
  9.                         alert(‘The logged in user is: ‘ + user[‘user’].username + ‘.’)
  10.                         }
  11.                 } catch (e) {
  12.                         alert("The session did not transfer")
  13.                 }
  14.         }, 500);
  15. });
  16.  

This is the basic mechanism that allows this to happen, but the next step would be securing with some sort of key and adapting this to your needs.

As stated earlier - on my app there are multiple domains being run by a single application. So I can save the a generated key to a table, and then use that key to re-connect with ajax.

© Copyright 2009, JoshMattVander. Powered by Wordpress
Valid XHTML 1.0 Strict : Valid CSS 2