Active Recordのgenerates_token_for:DBカラム不要で一時的なトークンを扱う機能 31 views Post @wakairo 16時間2026/03/02 17:02 generates_token_forとは generates_token_forは、特定の目的を持つトークンを生成し、そのトークンからレコードを検索・検証するための機能です。 Rails 7.1で標準機能として導入されました。 特長 DBへのデータ保存不要:トークンを保存するためのデータベースのカラムやテーブルを追加せずに利用できます。 目的別に分離:目的(purpose)ごとにトークンを分離できるため、別目的で生成されたトークンを使い回すことができません。 失効条件を設定可能:有効期限とモデルのデータ変化による失効条件を柔軟に設定できます。 改ざん耐性:署名付きのトークンのため、改ざん耐性があります。 使いどころ:一時的に有効なURLの送付 以下のような「一時的で目的が限定されたトークン付きURL」を送付する場面に適しています。 メールアドレス確認リンク 招待リンク マジックリンク(パスワードなしログイン) 一時アクセスリンク なお、APIの認証トークンのような永続的な用途には向きません。 Railsで永続的なトークンを扱いたい場合は、has_secure_tokenなどの利用を検討してください。 注意:パスワードリセットには専用APIあり Rails 8.0以降でhas_secure_passwordを利用している場合、パスワードリセット用トークンを扱う専用APIが自動的に提供されます。そのため、パスワードリセットの用途に限っては、自分でgenerates_token_forを定義する必要はありません。(詳しくは後述の補足を参照してください) 使い方(メールアドレス確認の例) ここでは「メールアドレス変更時の確認リンク」を題材に、基本的な使い方を説明します。 基本の流れ(定義・生成・検証) まず、モデルにgenerates_token_forを用いて、トークンの用途名(ここでは:email_verification)を定義します。 なお、用途名が異なっていれば複数定義することも可能です。 class User < ApplicationRecord generates_token_for :email_verification end トークンを生成する際は、対象のインスタンスに対してgenerate_token_forを呼び出します。 注意:モデルで定義する際は複数形のgenerates_token_forですが、 インスタンスから呼び出す際は単数形のgenerate_token_forになる点に注意してください。 user = User.first # 対象のレコードを取得(ここでは`first`で代替) token = user.generate_token_for(:email_verification) # => "BAhJIi..." (生成されたトークン文字列) 生成したトークンは、例えば以下のようにURLパラメータに載せてメールなどで送付するのが典型的な流れです。 # 例:メイラー等でのURL生成 email_verifications_url(token: token) # => "https://example.com/email_verifications?token=BAhJIi..." 受け取ったトークンからレコードを検索・検証するには、クラスメソッドのfind_by_token_forを使います。 有効なトークンならUserインスタンスが返り、無効なトークンや期限切れのトークンの場合はnilが返ります。 user = User.find_by_token_for(:email_verification, token) 有効期限による失効 定義時にexpires_inオプションを付与することで、トークンに有効期限(例:15分間)を設けることができます。 class User < ApplicationRecord generates_token_for :email_verification, expires_in: 15.minutes end モデルのデータ変化による失効 generates_token_forは、「一度状態が変わったら、古いトークンを使わせない」挙動を簡単に実装できます。 例えば、新しいメールアドレス確認用に生成されたトークンを、メールアドレスの変更が完了した後に無効化すれば、万が一流出しても悪用を防げます。 無効化の仕組みは「定義時のブロックの戻り値をトークンに埋め込み、検証時にその値が変わっていれば無効とみなす」というものです。 class User < ApplicationRecord generates_token_for :email_verification, expires_in: 15.minutes do # トークン生成時と検証時で`email`の値が異なれば(=メールアドレスが変更完了していれば)、 # 有効期限内であっても無効になる email end end 注意:ブロックの戻り値に機密情報を含めない ブロック内で返した値は、改ざん耐性はあるものの、暗号化されるわけではなく、デコードすれば読める形でトークンに埋め込まれます。 そのため、ブロックの戻り値には機密情報を含めてはなりません。 補足:パスワードリセット専用API Rails 8.0以降では、モデルでhas_secure_passwordを利用している場合、パスワードリセットトークン用の以下のメソッドがデフォルトで追加されます。 password_reset_token:トークン生成(インスタンスメソッド) find_by_password_reset_token:トークンからの検索と検証(クラスメソッド) find_by_password_reset_token!:同上(無効時に例外を発生させるバージョン) Rails 8.1で追加されたトークン有効期限の機能 さらにRails 8.1以降では、トークンの有効期限を柔軟に扱うための機能が追加されています。 has_secure_passwordの呼び出し時にreset_tokenオプションを通して有効期限を変更できるようになりました。 class User < ApplicationRecord has_secure_password reset_token: { expires_in: 1.hour } end また、以下のメソッドが追加されました。 password_reset_token_expires_in:設定されている有効期限の取得(インスタンスメソッド) 参考情報 Rails APIドキュメント:generates_token_for Rails APIドキュメント:has_secure_password GitHub:has_secure_passwordの実装コード 記入 プレビュー Markdownの書き方
@wakairo 16時間2026/03/02 17:02 generates_token_forとは generates_token_forは、特定の目的を持つトークンを生成し、そのトークンからレコードを検索・検証するための機能です。 Rails 7.1で標準機能として導入されました。 特長 DBへのデータ保存不要:トークンを保存するためのデータベースのカラムやテーブルを追加せずに利用できます。 目的別に分離:目的(purpose)ごとにトークンを分離できるため、別目的で生成されたトークンを使い回すことができません。 失効条件を設定可能:有効期限とモデルのデータ変化による失効条件を柔軟に設定できます。 改ざん耐性:署名付きのトークンのため、改ざん耐性があります。 使いどころ:一時的に有効なURLの送付 以下のような「一時的で目的が限定されたトークン付きURL」を送付する場面に適しています。 メールアドレス確認リンク 招待リンク マジックリンク(パスワードなしログイン) 一時アクセスリンク なお、APIの認証トークンのような永続的な用途には向きません。 Railsで永続的なトークンを扱いたい場合は、has_secure_tokenなどの利用を検討してください。 注意:パスワードリセットには専用APIあり Rails 8.0以降でhas_secure_passwordを利用している場合、パスワードリセット用トークンを扱う専用APIが自動的に提供されます。そのため、パスワードリセットの用途に限っては、自分でgenerates_token_forを定義する必要はありません。(詳しくは後述の補足を参照してください) 使い方(メールアドレス確認の例) ここでは「メールアドレス変更時の確認リンク」を題材に、基本的な使い方を説明します。 基本の流れ(定義・生成・検証) まず、モデルにgenerates_token_forを用いて、トークンの用途名(ここでは:email_verification)を定義します。 なお、用途名が異なっていれば複数定義することも可能です。 class User < ApplicationRecord generates_token_for :email_verification end トークンを生成する際は、対象のインスタンスに対してgenerate_token_forを呼び出します。 注意:モデルで定義する際は複数形のgenerates_token_forですが、 インスタンスから呼び出す際は単数形のgenerate_token_forになる点に注意してください。 user = User.first # 対象のレコードを取得(ここでは`first`で代替) token = user.generate_token_for(:email_verification) # => "BAhJIi..." (生成されたトークン文字列) 生成したトークンは、例えば以下のようにURLパラメータに載せてメールなどで送付するのが典型的な流れです。 # 例:メイラー等でのURL生成 email_verifications_url(token: token) # => "https://example.com/email_verifications?token=BAhJIi..." 受け取ったトークンからレコードを検索・検証するには、クラスメソッドのfind_by_token_forを使います。 有効なトークンならUserインスタンスが返り、無効なトークンや期限切れのトークンの場合はnilが返ります。 user = User.find_by_token_for(:email_verification, token) 有効期限による失効 定義時にexpires_inオプションを付与することで、トークンに有効期限(例:15分間)を設けることができます。 class User < ApplicationRecord generates_token_for :email_verification, expires_in: 15.minutes end モデルのデータ変化による失効 generates_token_forは、「一度状態が変わったら、古いトークンを使わせない」挙動を簡単に実装できます。 例えば、新しいメールアドレス確認用に生成されたトークンを、メールアドレスの変更が完了した後に無効化すれば、万が一流出しても悪用を防げます。 無効化の仕組みは「定義時のブロックの戻り値をトークンに埋め込み、検証時にその値が変わっていれば無効とみなす」というものです。 class User < ApplicationRecord generates_token_for :email_verification, expires_in: 15.minutes do # トークン生成時と検証時で`email`の値が異なれば(=メールアドレスが変更完了していれば)、 # 有効期限内であっても無効になる email end end 注意:ブロックの戻り値に機密情報を含めない ブロック内で返した値は、改ざん耐性はあるものの、暗号化されるわけではなく、デコードすれば読める形でトークンに埋め込まれます。 そのため、ブロックの戻り値には機密情報を含めてはなりません。 補足:パスワードリセット専用API Rails 8.0以降では、モデルでhas_secure_passwordを利用している場合、パスワードリセットトークン用の以下のメソッドがデフォルトで追加されます。 password_reset_token:トークン生成(インスタンスメソッド) find_by_password_reset_token:トークンからの検索と検証(クラスメソッド) find_by_password_reset_token!:同上(無効時に例外を発生させるバージョン) Rails 8.1で追加されたトークン有効期限の機能 さらにRails 8.1以降では、トークンの有効期限を柔軟に扱うための機能が追加されています。 has_secure_passwordの呼び出し時にreset_tokenオプションを通して有効期限を変更できるようになりました。 class User < ApplicationRecord has_secure_password reset_token: { expires_in: 1.hour } end また、以下のメソッドが追加されました。 password_reset_token_expires_in:設定されている有効期限の取得(インスタンスメソッド) 参考情報 Rails APIドキュメント:generates_token_for Rails APIドキュメント:has_secure_password GitHub:has_secure_passwordの実装コード
generates_token_forとは
generates_token_forは、特定の目的を持つトークンを生成し、そのトークンからレコードを検索・検証するための機能です。 Rails 7.1で標準機能として導入されました。特長
使いどころ:一時的に有効なURLの送付
以下のような「一時的で目的が限定されたトークン付きURL」を送付する場面に適しています。
なお、APIの認証トークンのような永続的な用途には向きません。 Railsで永続的なトークンを扱いたい場合は、
has_secure_tokenなどの利用を検討してください。注意:パスワードリセットには専用APIあり
Rails 8.0以降で
has_secure_passwordを利用している場合、パスワードリセット用トークンを扱う専用APIが自動的に提供されます。そのため、パスワードリセットの用途に限っては、自分でgenerates_token_forを定義する必要はありません。(詳しくは後述の補足を参照してください)使い方(メールアドレス確認の例)
ここでは「メールアドレス変更時の確認リンク」を題材に、基本的な使い方を説明します。
基本の流れ(定義・生成・検証)
まず、モデルに
generates_token_forを用いて、トークンの用途名(ここでは:email_verification)を定義します。 なお、用途名が異なっていれば複数定義することも可能です。トークンを生成する際は、対象のインスタンスに対して
generate_token_forを呼び出します。生成したトークンは、例えば以下のようにURLパラメータに載せてメールなどで送付するのが典型的な流れです。
受け取ったトークンからレコードを検索・検証するには、クラスメソッドの
find_by_token_forを使います。 有効なトークンならUserインスタンスが返り、無効なトークンや期限切れのトークンの場合はnilが返ります。有効期限による失効
定義時に
expires_inオプションを付与することで、トークンに有効期限(例:15分間)を設けることができます。モデルのデータ変化による失効
generates_token_forは、「一度状態が変わったら、古いトークンを使わせない」挙動を簡単に実装できます。 例えば、新しいメールアドレス確認用に生成されたトークンを、メールアドレスの変更が完了した後に無効化すれば、万が一流出しても悪用を防げます。無効化の仕組みは「定義時のブロックの戻り値をトークンに埋め込み、検証時にその値が変わっていれば無効とみなす」というものです。
注意:ブロックの戻り値に機密情報を含めない
ブロック内で返した値は、改ざん耐性はあるものの、暗号化されるわけではなく、デコードすれば読める形でトークンに埋め込まれます。 そのため、ブロックの戻り値には機密情報を含めてはなりません。
補足:パスワードリセット専用API
Rails 8.0以降では、モデルで
has_secure_passwordを利用している場合、パスワードリセットトークン用の以下のメソッドがデフォルトで追加されます。password_reset_token:トークン生成(インスタンスメソッド)find_by_password_reset_token:トークンからの検索と検証(クラスメソッド)find_by_password_reset_token!:同上(無効時に例外を発生させるバージョン)Rails 8.1で追加されたトークン有効期限の機能
さらにRails 8.1以降では、トークンの有効期限を柔軟に扱うための機能が追加されています。
has_secure_passwordの呼び出し時にreset_tokenオプションを通して有効期限を変更できるようになりました。また、以下のメソッドが追加されました。
password_reset_token_expires_in:設定されている有効期限の取得(インスタンスメソッド)参考情報