Rails

【Rails】hashid-railsを用いてIDを難読化・暗号化させる方法

Rails

 

今回はgem ‘hashid-rails’を用いてIDを難読化・暗号化させる方法についてまとめたいと思います。IDに数値を用いている場合、数値からユーザー数を特定されたり、URLが不正ユーザーにと送られてしまったりと様々な危険があるため、IDをそのまま使用している場合はhashid-railsを用いて特定されない値に変換しましょう。

hashid-railsとは

hashid-railsとは、IDを自動で暗号化(ハッシュ化)することで、機密情報が特定されることを防いでくれるgemになります。

This gem allows you to easily use Hashids in your Rails app. Instead of your models using sequential numbers like 1, 2, 3, they will instead have unique short hashes like “yLA6m0oM”, “5bAyD0LO”, and “wz3MZ49l”. The database will still use integers under the hood, so this gem can be added or removed at any time.

このgemを使用すると、RailsアプリでHashidsを簡単に使用できます。 1、2、3のような連番を使用するモデルの代わりに、「yLA6m0oM」、「5bAyD0LO」、「wz3MZ49l」のような一意の短いハッシュがあります。データベースは引き続き内部で整数を使用するため、このgemはいつでも追加または削除できます。

参考: hashid-rails

 

例えば「https://test-site/users/1/account」のように数値がURLにそのまま入ってしまうと、ユーザー数が特定されてしまったりURLが不正ユーザーに拡散されてしまったりと、危険な状況になる可能性があります。

しかしhashid-railsを用いることで、「https://test-site/users/JF751f/account」のようにIDを自動で暗号化し、アプリケーションの安全性を高めてくれます。

hashid-railsの使用方法

hashid-railsの使用方法をまとめると以下のようになります。

  1. Gemのインストール
  2. 暗号化したいモデルに「include Hashid::Rails」を記載
  3. パラメーターを暗号化

1. Gemのインストール

# Gemfile
gem 'hashid-rails'
% bundle install

2. 暗号化したいモデルに「include Hashid::Rails」を記載

hashid-railsの導入が完了したら、続いては暗号化したいモデルに「include Hashid::Rails」を記載します。

例えばUserのパラメーターを暗号化したい場合、以下のように記述します。

class User < ApplicationRecord
  include Hashid::Rails
end

 

たったこれだけの作業でhashid-railsを使用できる環境が整いました。

3. パラメーターを暗号化

最後にhashid-railsを用いてID部分を暗号化してみましょう。

link_toメソッドを用いてURLを生成している場合は、以下のように「@user.hashid」とすることでURLに暗号化された文字列が表示されるようになります。

<%= link_to '詳細を見る', accounts_user_path(@user.hashid) %>
# 生成されるURL例(ローカル環境)
http://localhost:3000/accounts/users/KmoHXZ

 

findメソッドを用いてパラメータを取得する場合も、以下のようにhashidを指定します。

@user = User.find(params[:hashid])
送られてくるパラメータが既に暗号化されている場合、「@user = User.find(params[:id])」といったこれまでの記述でも可能です。

find_byのような使い方も可能

先ほどはfindメソッドを用いて暗号化されたパラメータを受け取る方法について記載しましたが、hashid-railsではfind_byメソッドのような使い方も可能です。

# レコードがあった場合、そのレコードを返す
@person = Person.find_by_hashid(params[:hashid])
#=> <Person>

# レコードがない場合、nilを返す
@person = Person.find_by_hashid(params[:hashid])
#=> nil

暗号化のカスタマイズ

デフォルトではID部分は「”abcdefghijklmnopqrstuvwxyz”」「”ABCDEFGHIJKLMNOPQRSTUVWXYZ”」「”1234567890″」を組み合わせた6文字で構成されますが、この部分はカスタマイズが可能です。

initializers以下にhashids.rbを作成し、その中に設定を書き込んでいきます。

% touch config/initializers/hashids.rb
Hashid::Rails.configure do |config|
  # The salt to use for generating hashid. Prepended with pepper (table name).
  config.salt = ""
  config.pepper = table_name

  # 文字数
  # The minimum length of generated hashids
  config.min_hash_length = 6

  # 暗号化に使用される文字
  # The alphabet to use for generating hashids
  config.alphabet = "abcdefghijklmnopqrstuvwxyz" \
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
                    "1234567890"

  # Whether to override the `find` method
  config.override_find = true

  # Whether to override the `to_param` method
  config.override_to_param = true

  # Whether to sign hashids to prevent conflicts with regular IDs (see https://github.com/jcypret/hashid-rails/issues/30)
  config.sign_hashids = true
end

まとめ

  • IDに数値を用いている場合、数値からユーザー数やURLといった機密情報が特定されてしまう恐れがある
  • hashid-railsとは、IDを自動で暗号化(ハッシュ化)することで、機密情報が特定されることを防いでくれるgem
  • hashid-railsではfind_byメソッドのような使い方も可能
  • 暗号化部分をカスタマイズすることも可能

参考

hashid-rails

 

 

今回はgem ‘hashid-rails’を用いてIDを難読化・暗号化させる方法についてまとめました。IDを難読化する方法は他にも色々あるようですが、hashid-railsを用いる方法が一番早く簡単だと思います。導入がまだの方はぜひ検討してみてください。