🐟
[Rails]idにuuid(乱数)
uuidとは
Universally Unique Identifierの略。
下記のようなユニークなidのこと。
URLに含まれます。
http://localhost:3000/admin/articles/d8d712e9-77ec-4e4d-900b-98ad07f73c66/preview
uuidを使う理由
URLのidから情報を推測しづらくするためです。
Rails標準として提供している整数値のidを用いた場合、人間がデータを推測することが容易になってしまい、様々なリスクに繋がります。
hhtps://example.co.jp/users/1
この1
の部分が、1
という識別子を持ったユーザーであると推測できます。
この値を別に変えると他のユーザーのページにアクセスできてしまうかもしれません。
大事なのは、このようなことができるかどうか、ではなくユーザーにそのような考えを抱かせてしまう可能性があるということです。
uuidを使うことで、用意に推測できないようにし、問題を回避します。
d8d712e9-77ec-4e4d-900b-98ad07f73c66
uuidを使う注意点
ただ、uuidを使うとfirstやlastなどでデータを取得する際に注意が必要です。
User.first
すると下記のようなSQLが発行されます。
SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1
idの値はd8d712e9-77ec-4e4d-fef-98ad07f73c66
のように乱数となるため、このレコードを取得できるとは限らないということです。
すでに既存のプロジェクトにuuidを導入する場合は、idによる order
, first
, last
などを使っていないか確認する必要があります。
idにuuidを使う
既存のカラムに追加する場合
デフォルトではテーブルのidにはinteger型で主キーとして使用されています。
これをstring(文字列)型に変更します。
rails g migration ChangeColumnToUser
class ChangeColumnToUser < ActiveRecord::Migration[5.2]
# 変更内容
def up
change_column :users, :id, :string
end
# 変更前の状態
def down
change_column :users, :id, :integer
end
end
新規で使う場合
はじめから新規でテーブルを作成したときにidの型をstring型に変更しておきます。
class CreateArticles < ActiveRecord::Migration[5.2]
def change
create_table :articles do |t|
t.belongs_to :category
t.belongs_to :author
t.string :uuid
t.string :slug
t.string :title
t.text :description
t.text :body
t.integer :state, default: 0, null: false
t.datetime :published_at
t.timestamps
t.datetime :deleted_at
t.index :uuid
t.index :slug
t.index :published_at
t.index :deleted_at
end
end
end
モデルにuuidを定義
下記のように使いたいモデルで定義します。
class Article < ApplicationRecord
略
before_create -> { self.uuid = SecureRandom.uuid }
略
end
SecureRandom.uuid
でuuidを生成して返します。
SecureRandom.uuidメソッド
uuid(乱数)を生成するRubyメソッドです。
[1] pry(main)> SecureRandom.uuid
=> "008d0a50-4a81-4ade-8ed8-008ef4a427e6"
[2] pry(main)> SecureRandom.uuid
=> "6b604f7f-b49f-4226-9428-b2a3f8861985"
参考
Discussion