DEV Community

Thierry Chau
Thierry Chau

Posted on

How to Use Sqids in Rails to Obfuscate IDs

When developing web applications, it’s common to expose database IDs in URLs, such as example.com/posts/123. While this is convenient, it has potential drawbacks. Sequential IDs can reveal information about your database, like the number of records or the order in which they were created. To address this, developers often look for ways to obfuscate these IDs while keeping them reversible for internal use. This is where SQIDs come into play.

What is Sqids?

Sqids is a library designed to generate short, non-sequential, and URL-friendly IDs from integers. Unlike UUIDs, which are long and not user-friendly, Sqids provide a compact alternative that can be used in URLs to hide the real database IDs. They’re particularly useful in scenarios where you want to obfuscate your IDs without modifying your database schema or introducing significant overhead.

Why Not Use UUID?

UUIDs (Universally Unique Identifiers) are often used as an alternative to numeric IDs for their uniqueness across distributed systems. However, UUIDs have a few drawbacks:

  • Length: UUIDs are typically 36 characters long, which can make URLs cumbersome.
  • Not Sequential: While they are unique, UUIDs are not sequential, making indexing in databases less efficient.

On the other hand, Sqids offer a balance between security, URL friendliness, and reversibility, making them an ideal choice for many applications.

Implementing Sqids in Rails

Here’s how you can implement Sqids in a Rails application using a concern. This approach ensures that you don’t have to modify your database schema, and you can easily integrate it with your existing models.

Step 1: Install the Sqids Gem

First, add the Sqids Ruby gem to your Gemfile:

gem 'sqids' 
Enter fullscreen mode Exit fullscreen mode

Run bundle install to install the gem.

Step 2: Create a Concern for Sqids

Next, create a concern to encapsulate the logic for encoding and decoding Sqids:

# app/models/concerns/sqids_encodable.rb module SqidsEncodable extend ActiveSupport::Concern # arguments here are optional ; you can change the alphabet to change the encoding sequence SQIDS = Sqids.new(alphabet: 'k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', min_length: 8) def to_param sqid end def sqid SQIDS.encode([id]) end class_methods do def find_by_sqid(sqid) find(SQIDS.decode(sqid).first) end end end 
Enter fullscreen mode Exit fullscreen mode

This concern does a few key things:

  • to_param method: Overrides the default to_param method to return the SQID instead of the numeric ID. This ensures that Rails uses the SQID in URLs.
  • sqid method: Encodes the model’s ID using Sqids.
  • find_by_sqid method: Allows you to find a record by its SQID, decoding it back to the original ID.

Step 3: Use the Concern in Your Models

To use this in a model, include the SqidsEncodable concern:

# app/models/post.rb class Post < ApplicationRecord include SqidsEncodable # Your model logic here end 
Enter fullscreen mode Exit fullscreen mode

With this setup, whenever you generate a URL for a Post, Rails will automatically use the SQID instead of the numeric ID.

Step 4: Use Sqids in Your Controllers

When querying for a record, use find_by_sqid:

# app/controllers/posts_controller.rb class PostsController < ApplicationController def set_post @post = Post.find_by_sqid(params[:id]) end # Other controller actions end 
Enter fullscreen mode Exit fullscreen mode

This ensures that Rails can correctly retrieve the record using the obfuscated ID.

Conclusion

We went from example.com/posts/123 to something like example.com/posts/5sQ1BZoD.

Sqids offer a practical solution for obfuscating database IDs in a Rails application. They allow you to hide the actual IDs from users, while still being able to reverse the process internally. Compared to UUIDs, SQIDs provide a more user-friendly, compact, and efficient approach.

It’s important to note that while Sqids obfuscate the IDs, they do not encrypt them. If you require encryption for your IDs, you’ll need to look into more robust security measures. However, for most applications, SQIDs strike a good balance between security and usability.

Learn more about Insecure Direct Object Reference
Learn more about Sqids | GitHub repository

Top comments (0)