[Rail-API] ログイン機能を実装する

学習記録

はじめに

Rails apiにsorceryを導入して、ログイン機能を実装します。

sorceryのインストール

gemfileにsorceryを追記しましょう。

gem 'sorcery'
> bundle install

下記コマンドでsorceryを導入しましょう。sorceryの初期化ファイル、マイグレーションファイル、Userモデルが作成されます。

> rails g sorcery:install

新たにマイグレーションファイルが作成されますが、すでにusersテーブルがある場合は削除しても構いません。

ルーティング設定

authenticationでPOST形式のリクエストを受け取るように追記しましょう。

Rails.application.routes.draw do
  namespace :api, format: 'json' do
    namespace :v1 do
      resources :articles, only: %i[index show]
      post 'authentication', to: 'authentications#create' # ←追記
    end
  end
end

autnenticationsコントローラ作成

ログイン処理をするコントローラを記述しましょう。 @userがない場合は、例外処理が出るようにしています。

module Api
  module V1
    class AuthenticationsController < BaseController
      def create
        @user = login(params[:email], params[:password])

        raise ActiveRecord::RecordNotFound unless @user

        json_string = UserSerializer.new(@user).serialized_json
        render json: json_string
      end
    end
  end
end

Baseコントローラに追記

Baseコントローラに、def form_authenticity_token; endを追記しましょう。 ユーザーがログインする際にCSRFトークンがリセットされるのですが、それを行うform_authenticity_tokenメソッドがRails-APIに存在しません。 Rails-APIとしてSorcertyを使用する際は必須ですので、必ず追記しましょう。

module Api
  module V1
    class BaseController < ApplicationController
      include Api::ExceptionHandler

      private

      def form_authenticity_token; end
    end
  end
end

FactoryBotを確認

FactoryBotの内容が間違えたまま、rails db:seedでデータを作成してしまうと、正しくデータが返ってきません。 今一度、FactoryBotが正しいか確認します。

FactoryBot.define do
  factory :user do
    sequence(:name) { |n| "MyString#{n}" }
    sequence(:email) { |n| "user+#{n}@example.com" }
    password { 'password' }
  end
end

コンソールでuserデータを確認します。

irb(main):001:0> User.first
   (4.7ms)  SELECT sqlite_version(*)
  User Load (3.9ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "MyString1", email: "user+1@example.com", crypted_password: "$2a$10$dHeZ.53RUP.8YEDqo2YqBu6AgJTcpICmymU8m3aCWtM...", salt: "Haf68sx26f1avsrLdFmy", created_at: "2022-07-17 14:00:40", updated_at: "2022-07-17 14:00:40">

crypted_passwordの内容が文字列になっていれば、大丈夫でしょう。

Postmanで確認

Postmanの設定をPOSTにし、localhost:3000/api/v1/authenticationと正しく入力し、Bodyに替え、KEYとVALUEを正しく入力します。 他のモードだと正しくデータが返ってこないのでご注意ください。

https://i.gyazo.com/9fb1da854b8eec2876075dfe787722fa.png

参考

Rails-APIでsorceryを使ったらundefined local variable or method `form_authenticity_token'と怒られた - Qiita
概要 Rails-APIにて認証用のgem sorceryを使ってloginメソッドを叩いた時に undefined local variable or method `form_authenticity_token' と...

コメント

タイトルとURLをコピーしました