RefCode

A ruby gem for converting arbitrary Ruby objects into encrypted, URL-safe strings. The strings can be easily decrypted later for use in your application.

RefCode was conceived as a way to attach referral data to tracking links. Encryption makes it unlikely that the links will be tampered with. Still, it is not recommended for sensitive data!

Why would you want this?

Lets say your app needs to track activity around certain pages that are shared among your users. Using RefCode, you can generate URLs pointing to these pages that are meant to be shared across various channels (email, facebook, etc). These links can carry a small amount of encoded data as part of the URL that will guarantee that any events you track due to visits to these links can make use of this extra encoded data. The data might include, for example, which user originally shared the link and on which channel she did so.

A secondary feature offered by the Refcode::Encodable mixin is the ability to guarantee that a given code works only for one (or more) specific page. For example, by using a unique value for the salt option that is tied to a single record, the generated code cannot be used with any other record. See the usage example below for a demonstration of this.

Implementation

Installation

Add this line to your application's Gemfile:

gem 'refcode'

And then execute:

$ bundle

Or install it yourself as:

$ gem install refcode

Usage

RefCode can be used in two ways. Most simply, you can use the Refcode::Encoder class directly.

encoder = Refcode::Encoder.new do |e|
  e.secret = "a long crunchy secret"
  e.salt = "some salt"
end

something = OpenStruct.new(channel: 'facebook', action: 'message', user_id: 43765)
encoded_param = encoder.encode something

# in some future request:

something = encoder.decode params[:encoded_param]
puts something.channel #=> 'facebook'

For added convenience when using Refcode with an ORM such as ActiveRecord, a module called Refcode::Encodable is also provided.

class Job < ActiveRecord::Base
  include Refcode::Encodable
  has_refcode secret: 'a long crunchy secret', salt: :id
end

# the salt option of the has_refcode method can accept a proc/lambda, string
# or a symbol representing an existing method on the class (id in this case)

# in some controller code:

@job = Job.find params[:id]
referral_code = @job.generate_refcode channel: 'facebook', action: 'message', user_id: 43765

# and in another action:

@job = Job.find params[:id]
referral_data = @job.parse_refcode params[:encoded_param]

Features for 1.0

  • ~~Encodable mixin~~
  • ~~Better exception handling~~
  • More complete tests against encoding non-core ruby class values

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request