Rails7のAPIモードでDevise Token Authを使います
準備
私が以前に作成したこちらの記事をもとに開発環境を構築した状態から始めます。
Gemfileに以下のGemを記載した後に、bundle installを実行します。
gem "rack-cors"
gem 'devise'
gem 'devise_token_auth'
gem 'devise-i18n'
次のコマンドでdeviseとdevise_token_authをインストールし、Userモデルを作成します。
rails g devise:install
rails g devise_token_auth:install User auth
続いて、認証を行うコントローラーとログインユーザー情報を取得するコントローラーを作成します。
rails g controller api/v1/auth/registrations
rails g controller api/v1/auth/sessions
各コントローラーを修正します。
class Api::V1::Auth::RegistrationsController < DeviseTokenAuth::RegistrationsController
private
def sign_up_params
params.permit(:email, :password, :password_confirmation, :name)
end
end
class Api::V1::Auth::SessionsController < ApplicationController
def index
if current_api_v1_user
render json: { is_login: true, data: current_api_v1_user }
else
render json: { is_login: false, message: "ユーザーが存在しません" }
end
end
end
access-token,uid,clientの値をクライアント側で利用したいので、次のようにCORSを設定します。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins "localhost:3000"
resource "*",
headers: :any,
expose: %w[access-token uid client],
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
ルーティングの設定を行います。
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
registrations: 'api/v1/auth/registrations'
}
namespace :auth do
resources :sessions, only: [:index]
end
end
end
end
分かりやすくするために日本語に設定します。
docker compose exec api rails g devise:i18n:locale ja
日本語を適用するためにapplication_controller.rbを次のように修正します。
class ApplicationController < ActionController::API
include DeviseTokenAuth::Concerns::SetUserByToken
before_action do
I18n.locale = :ja
end
end
Rails7では、セッションを使用しない場合にセッションへのアクセスがあるとエラーが発生するようですので、application.rbを次のように修正します。
require_relative "boot"
require "rails/all"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Api
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.0
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
# Only loads a smaller set of middleware suitable for API only apps.
# Middleware like session, flash, cookies can be added back manually.
# Skip views, helpers and assets when generating a new resource.
config.api_only = true
config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
end
end
今回はリクエストごとにトークンが変更されないよう設定します。
config.change_headers_on_each_request = false
忘れないうちに次のコマンドを実行します。
docker compose exec api rails db:migrate
動作確認
ここまでできたらいくつかのメソッドの動作確認をしてみます。今回はAdvanced REST clientを用います。
サインアップ
メソッドはPOST
リクエストURLはhttp://localhost:3001/api/v1/auth
Bodyに次の画像のように値を入力します。
SENDを押下して次のようなレスポンスが帰ってきたら成功です。
また、DETAILSを開くとuid, access-token, clientの値が帰ってきていることが確認できます。
サインイン
メソッドはPOST
リクエストURLはhttp://localhost:3001/api/v1/auth/sign_in
Bodyにemailとpasswordを入力し、SENDを押下します。
次のようなレスポンスが帰ってきたら成功です。
ログインユーザー情報の取得
メソッドはGET
リクエストURLはhttp://localhost:3001/api/v1/auth/sessions
Headersタブを選択し、DETAILSから確認できるuid,client,access-tokenの値を入力します。SENDを押下して次のようなレスポンスが帰ってきたら成功です。
サインアウト
メソッドはDELETE
リクエストURLはhttp://localhost:3001/api/v1/auth/sign_out
Bodyにui,client,access-tokenの値を入力し、SENDを押下します。
次のようなレスポンスが帰ってきたら成功です。
まとめ
Devise Token Authを用いて認証機能のバックエンドを作成し、いくつかのメソッドの動作確認を行いました。
Discussion