🐘

devise_token_auth でユーザー登録機能を実装する

2023/12/28に公開

概要

SPA での新規アプリケーションを実装するにあたり、
devise_token_auth gem を使って、トークンベースの認証機能を実装することにしました。

ということでまずはユーザーの登録 API の実装をしていきます。

トークンベースの認証とは

Web アプリケーションの認証方法として、以下の2つが比較されることが多いです。

  • セッションベースの認証
  • トークンベースの認証

セッションベース

セッションベースでは、ユーザーがログインすると、サーバー側でセッション ID が作成され、Coockie に保存されます。以降のリクエストでは、ブラウザはセッション ID を含む Cookie をサーバに送信することで、「俺は〇〇だぜ」というのをサーバに知らせます。

コードでいうと以下のようなものが多いです。

class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to user_path(user), notice: 'ログインしました。'
    else
      flash.now[:alert] = 'メールアドレスまたはパスワードが無効です。'
      render 'new'
    end
  end
end

トークンベース

トークンベースでは、ユーザーがログインすると、サーバー側でトークンが作成され、Header に入れてユーザーに返します。以降のリクエストでは、このトークンを、リクエストヘッダーにいれて、「俺は〇〇だぜ」というのをサーバに知らせます。
コードはこれから書く devise_token_auth 等を使ったものです。

必要な gem の追加

Gemfile に以下を追加して、bundle install してください。

gem 'devise'
gem 'devise_token_auth'

devise_token_auth gem だけでも試しましたが、devise_token_authdevise の拡張であるため、どちらもないとうまく動かないようです。

コマンドで必要なファイルを作成

以下のコマンドを実行します。

rails generate devise:install

以下のファイルが作成されます。
特に何も変更しなくて問題ありません。

  • config/initializers/devise.rb
  • locales/devise.en.yml

次に以下のコマンドを実行します。

rails generate devise_token_auth:install User auth

これで、User モデルに、認証に必要な属性やメソッドを含むようにしてくれます。
また、/auth のパスで、ユーザーに対するサインアップやサインイン、サインアウトができるようにしてくれます。
作成、変更されるファイル配下。

  • models/user.rb
  • config/initializers/devise_token_auth.rb
  • config/routes.rb
  • db/migrate/〇〇_devise_token_auth_create_ursers.rb

users テーブル作成

作成された migration ファイルを DB に反映させます。

rails db:migrate

ルーティングの作成

今回は POST api/v1/auth のエンドポイントにユーザーの登録 API を実装します。
以下のように routes.rb を編集します。

  namespace :api do
    namespace :v1 do
      namespace :auth do
        mount_devise_token_auth_for 'User', controllers: {
          registrations: "api/v1/registrations"
        }
      end
    end
  end

controllers オプションに関してはおそらく Rails のデフォルトのものではなく、
devise_token_auth もしくは devise で定義されているものだと思います。
(違っていたらご指摘お願いします。)

おそらく devise_token_auth 側で定義している registrations_controller を、
このアプリケーションにマッピングさせるもの。

sessions_controller をマッピングさせたいときは、sessions: "api/v1/sessions" のように書きます。

コントローラの作成

routes.rb で api/v1/registrations とマッピングさせたので、以下のファイルを作成します。
controllers/api/v1/registrations_controller.rb

module Api
  module V1
    class RegistrationsController < DeviseTokenAuth::RegistrationsController

    end
  end
end

これで devise_token_auth の registrations_controller を継承します。
https://github.com/lynndylanhurley/devise_token_auth/blob/6b0659f18c678b319913d0fb053e96aa555857aa/app/controllers/devise_token_auth/registrations_controller.rb

動作確認

今回は Postman を使って動作確認します。
以下のように リクエストボディを設定し、send します

以下のようなレスポンスが返り、ユーザーが作成されたことがわかります。

また、Headers からレスポンスヘッダーを確認すると、access-token の項目があり、
トークンが返ってきていることが確認できました。

次回以降のリクエストでは、これをリクエストヘッダーに含めることで、「俺は〇〇だぜ」
というのをサーバーに証明することができます。

devise_token_auth でトークンを作ってヘッダーに詰めているのはこのあたり。

Discussion