🐟

[Rails]idにuuid(乱数)

2021/10/18に公開

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"

参考

https://docs.ruby-lang.org/ja/latest/method/SecureRandom/s/uuid.html

Discussion