Contents
Rails 7 APIモードでトークン認証を実装する手順とコード例
Rails 7 APIモードでは、Webアプリケーションの軽量化やAPI専用の設計パターンが求められます。本記事では、devise_token_authやJWTなどのライブラリを活用し、セキュアなトークン認証を実装する方法をステップバイステップで解説します。初学者でも導入可能な手順とコード例を提供します。
Rails 7 APIモード環境の初期設定
API専用アプリケーションでは、--apiオプションを使うことで不必要な機能(例:JavaScriptサポート)を省略できます。本セクションでは、プロジェクト作成からライブラリのインストールまでを解説します。
API専用アプリケーションの作成手順
-
Railsプロジェクトの新規作成
rails new api_app --apiコマンドでAPIモード専用アプリケーションを作成します。このオプションは、リレーショナルDB以外の機能を省略した構成になります。 -
Gemfileへのライブラリ追加
json:apiやdevise_token_authなどの依存関係を追加します。
ruby
gem 'json:api'
gem 'devise_token_auth', '~> 1.3' # 適切なバージョンを指定(2026年時点の記述は誤り) -
Bundle Installの実行
bundle installでインストールしたライブラリを反映します。
必要ライブラリの導入と特徴
- json:api: JSON API規格に準拠したレスポンス形式を提供し、API設計の一貫性を確保します。
- devise_token_auth: Deviseに基づくトークン認証機能を拡張。JWTと併用するケースも存在しますが、独自のトークン発行ロジックを持ちます。
トークン発行処理の実装
トークンはユーザーがログイン時に発行され、APIリクエスト時に認証に使用されます。このセクションでは、Userモデルにトークンカラムを追加し、DeviseやJWTライブラリを使って発行ロジックを実装します。
認証モデルの設計
-
Userモデルへのトークンカラムの追加
ユーザーの認証に必要なトークン情報を保存するため、tokenカラムと有効期限管理用のexpires_atカラムを追加します。
bash
rails generate migration AddTokenAndExpiresAtToUsers token:string:index expires_at:datetime -
Deviseモジュールの導入
devise_token_authを使用する場合は、以下のようにUserモデルにモジュールを追加します。
ruby
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:token_authenticatable # トークン認証用モジュール
end
トークン発行APIの作成
-
トークン発行用コントローラーの生成
Devise Token Authの提供するTokenAuthenticatableを活用し、認証用エンドポイントを生成します。
bash
rails generate devise_token_auth:install User auth -
トークン発行処理の実装
Devise Token Authは、POST /auth/sign_inのようなエンドポイントでトークンを発行します。リクエストボディにメールアドレスとパスワードを送信します。
json
{
"email": "[メールアドレス削除]",
"password": "secure_password"
} -
レスポンスの確認
成功時は、access_tokenやexpires_inといった情報が返されます。失敗時は401エラーが返されるように設定されています。
⚠️ 注意:
access_tokenなどのフィールド名はライブラリバージョンにより変化する可能性があります。具体的な内容は実装時のAPI仕様書を参照してください。
トークンベースセキュリティ対策の実装
トークン認証では「有効期限管理」や「リフレッシュトークン」などの仕組みが必須です。ここでは、トークン発行時にexpires_atを設定し、リフレッシュトークン用モデルを作成する方法を紹介します。
有効期限管理の設計
-
Expires_Atカラムの追加
usersテーブルにexpires_atカラムを追加し、発行時に現在時刻をもとに有効期間(例: 1日)を設定します。
ruby
add_column :users, :expires_at, :datetime -
トークンの期限切れ処理
有効期限が切れたトークンは自動的に無効化されます。before_createフックでexpires_inを設定します。
ruby
before_create :set_expiration
private
def set_expiration
self.expires_at = Time.now + 1.day
end
リフレッシュトークンの仕組み
リフレッシュトークンは、ユーザーが一定期間アクセスしなかった場合に再発行されるトークンです。
-
リフレッシュトークン用モデルの作成
refresh_tokensというモデルを作成し、user_idとtokenを格納します。
bash
rails generate model RefreshToken user:references token:string:index -
リフレッシュ処理のロジック
有効期限が切れたトークンは、リフレッシュトークンを発行して再認証します。以下のようにbefore_actionでチェックできます。
ruby
before_action :refresh_token, if: :token_expired?
private
def token_expired?
current_user.expires_at < Time.now
end
def refresh_token
# 新しいトークンを発行する処理(例: JWT.generate(user.id)など)
end
Devise Token AuthとJWTライブラリの活用法
Devise Token Authは、トークン認証の自動化が可能なライブラリですが、JWTとの比較や組み合わせも検討する必要があります。
devise_token_authの導入手順
-
Gemfileに追加
ruby
gem 'devise_token_auth' -
モデル設定
Userモデルにtoken_authenticatableモジュールを含めます。 -
エンドポイントの生成
bash
rails generate devise_token_auth:install User auth
JWTとDevise Token Authの比較
| 方式 | セキュリティ | 有効期限管理 | リフレッシュトークンの必要性 |
|---|---|---|---|
| JWT | 高(暗号化された情報内包) | 手動設定可能 | 必要(通常、リフレッシュトークンを発行) |
| Devise Token Auth | 中~高(自動管理のため安定性が高め) | 自動で管理 | 可能(オプションで有効化) |
JWTはユーザー情報がトークンに内包されるため、セキュリティ面では強力ですが、有効期限や再発行処理を自分で実装する必要があります。一方、Devise Token Authはその多くを自動化している点が利点です。
APIリクエスト時のトークン認証フロー
APIリクエスト時にトークンを使用するためには、AuthorizationヘッダーにBearerトークンを設定します。ここでは、リクエスト処理と検証の実装例を解説します。
認証ヘッダーの形式
|
1 2 3 4 |
GET /api/v1/users HTTP/1.1 Authorization: Bearer <access_token> Content-Type: application/json |
<access_token>は、前セクションで発行されたトークンを指定します。通常、JWTやDevise Token Authが生成するアクセス・リフレッシュトークンのいずれかです。
トークン検証の実装例
以下のように、before_actionフィルターを使用してトークンの有効性を確認できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class ApplicationController < ActionController::API before_action :authenticate_user! private def authenticate_user! # Authorizationヘッダーからトークンを取り出す token = request.headers['Authorization'].split(' ').last # ユーザーが存在するか確認し、存在しない場合にエラーを返す @current_user = User.find_by(token: token) render json: { error: '未認証' }, status: 401 unless @current_user end end |
このコードでは、ヘッダーからトークンを取り出し、usersテーブルのレコードと照合します。一致しない場合はエラーを返却します。
テスト環境での検証方法
実装した機能が正しく動作するか確認するために、テスト環境での検証が必要です。ここでは、RSpecによる自動テストとPostmanでの手動検証の方法を紹介します。
RSpecによる認証テスト
-
FactoryBotでトークン発行のシミュレーション
FactoryBotを使ってユーザーを作成し、リファレンス用トークンを生成します。
ruby
let!(:user) { create(:user, token: 'test_token') } -
コントローラーのテストケース
認証が通る場合と通らない場合を検証できます。
ruby
describe '#index' do
context '認証されているとき' do
it '200ステータスコードで成功' do
get '/api/v1/users', headers: { Authorization: "Bearer test_token" }
expect(response).to have_http_status(200)
end
endcontext '認証されていないとき' do
it '401ステータスコードで失敗' do
get '/api/v1/users'
expect(response).to have_http_status(401)
end
end
end
Postmanでの手動検証
Postmanを使うことで、以下のようなフローを確認できます。
-
トークン発行のリクエスト
POST /auth/sign_inエンドポイントにメールとパスワードを送信します。
json
{
"email": "[メールアドレス削除]",
"password": "secure_password"
} -
レスポンス確認
トークンが返ってくるか確認し、Authorizationヘッダーに設定してリソース取得を試行します。
結論まとめ
Rails 7 APIモードでは、以下のような導入が推奨されます。
- API専用プロジェクトの作成(
--apiオプション) - Devise Token AuthとJWTの併用・比較による選択
- セキュリティ強化として有効期限管理とリフレッシュトークンの導入
実装に際しては、本記事で紹介したコード例を参考にし、テスト環境での検証(RSpecやPostman)を必ず行うことが重要です。