Rails/ActiveRecord::Base acts_as_obfuscated – hide your object ids

September 27th, 2009

I’ve always liked the idea of obfuscating the ids of my ActiveRecord::Base objects when using them in url. There’s lots of ways to go about this and through past projects I’ve used various mechanisms to accomplish it. Sometimes it’s nice and others it’s required. You might want to hide the number of users/objects/whatevers you have in you system or make it harder for malicious users to gain access to resources by guessing urls.

Well regardless of the reason(s) I’ve created a simple plugin/mixin, acts_as_obfuscated, that does exactly this with a single line of code. An example is in order:

class User < ActiveRecord::Base
  acts_as_obfuscated

  ...
end

and that's it.

$ ./script/console
Loading development environment (Rails 2.3.4)
>> u = User.create(:name => 'Bob')
=> #
>> u.id
=> 4
>> u.eid
=> "diBGnp"
>> User.find(u.id)
=> #
>> User.find(u.eid)
=> #
>>

The piece that's not shown above is an implementation of to_param.

def to_param
    self.eid
end

The effect of this is that anywhere you provider a user object in an 'id => user' param you get the self.eid rather than the default to_param of self.id. So a url that would look like http://mysite.com/users/4 would become http://mysite.com/users/diBGnp.

=link_to(user.name, :controller => 'users', :action => 'show', :id => user)

<a href="http://mysite.com/users/diBGnp">Bob</a>

acts_as_obfuscated doesn't get int the way of custom to_param functions so long as the first portion is the acts_as_obfuscated to_param function:

class User < ActiveRecord::Base
  acts_as_obfuscated

  def to_param
    CGI.escape("#{super.to_param}-#{self.name}").gsub(/\./, '_')
  end
end

$ ./script/console
Loading development environment (Rails 2.3.4)
u= U>> u= User.last
=> #
>> u.to_param
=> "diBGnp-Bob"
>> User.find(u.to_param)
=> #

That will allow you to have seo/ad placement friendly urls without exposing your internal object identifiers.

Anyway, check it out, use it, let me know what you think. The code can be found on github: http://github.com/ross/acts_as_obfuscated.

It can be installed as a plugin by running the command:

./script/plugin install git://github.com/ross/acts_as_obfuscated.git

If you want to see it in action check out: ClBrow - A Visual way to Shop Craigslist, which is a bit slower than I'd like to do the load on my dreamhost db, but hopefully I'll get around to fixing that soon...

-rm