1. Gemのインストール
まず、JWTを扱うためのGemをインストールします。gem 'jwt'をGemfileに追加し、bundle installを実行します。
# Gemfile
gem 'jwt'
bundle install
2. 秘密鍵の準備
JWTを署名するための秘密鍵を設定します。これを環境変数に保存するか、Railsのcredentialsに保存します。
# .envファイルに追加 (dotenv gemを使用している場合)
JWT_SECRET_KEY=your_secret_key
3. JWTを生成するメソッドの作成
コントローラーやサービスクラスで、JWTを生成するメソッドを作成します。
require 'jwt'
class JsonWebToken
SECRET_KEY = Rails.application.credentials.jwt_secret_key || ENV['JWT_SECRET_KEY']
def self.encode(payload, exp = 24.hours.from_now)
payload[:exp] = exp.to_i
JWT.encode(payload, SECRET_KEY)
end
def self.decode(token)
decoded = JWT.decode(token, SECRET_KEY)[0]
HashWithIndifferentAccess.new decoded
rescue JWT::DecodeError
nil
end
end
4. ユーザーログイン時にJWTを生成
ユーザーログイン時にJWTを生成して、クライアントに返します。
class AuthenticationController < ApplicationController
def login
@user = User.find_by(email: params[:email])
if @user && @user.authenticate(params[:password])
token = JsonWebToken.encode(user_id: @user.id)
render json: { token: token }, status: :ok
else
render json: { error: 'Invalid credentials' }, status: :unauthorized
end
end
end
5. 認証フィルターを設定
トークンを検証して、ユーザーを認証するフィルターを設定します。
class ApplicationController < ActionController::API
before_action :authorize_request
private
def authorize_request
header = request.headers['Authorization']
header = header.split(' ').last if header
decoded = JsonWebToken.decode(header)
@current_user = User.find(decoded[:user_id]) if decoded
rescue ActiveRecord::RecordNotFound => e
render json: { errors: e.message }, status: :unauthorized
rescue JWT::DecodeError => e
render json: { errors: e.message }, status: :unauthorized
end
end
6. 認証が必要なコントローラーにフィルターを適用
特定のコントローラーに対して、認証を強制するようにします。
class UsersController < ApplicationController
before_action :authorize_request, only: [:show, :update, :destroy]
def show
render json: @current_user
end
end
おまけ
jwtの実装の際の手順は下記の通り
-
ユーザーがログイン情報を入力
ユーザーがフロントエンドのログインフォームに情報を入力します。 -
POSTリクエストの送信
フロントエンドは、資格情報を含むPOSTリクエストをRailsアプリケーションの/loginエンドポイントに送信します。 -
ユーザーの認証
Railsアプリケーションは受け取った資格情報を使用してユーザーを認証します。 -
JWTトークンの生成
認証が成功すると、ユーザー情報を含むJWTトークンが生成されます。 -
JWTトークンの受信と保存
フロントエンドは、Railsから返されたJWTトークンを受け取り、ローカルストレージなどに保存します。 -
保護されたエンドポイントへのリクエスト
フロントエンドは、JWTトークンをAuthorizationヘッダーに含めて、保護されたエンドポイントにリクエストを送信します。 -
JWTトークンの検証
Railsアプリケーションは受け取ったJWTトークンを検証します。 -
アクセスの許可または拒否
JWTトークンが有効であればアクセスを許可し、無効であれば拒否します。 -
レスポンスの受信
フロントエンドは、Railsアプリケーションからのレスポンスを受け取り、ユーザーに表示します。