DEV Community

kaede
kaede

Posted on

Rails 基礎 Part 06 -- devise でログインをした上で、API UT を叩く

why

Kotlin で API を作った時、ログイン機能まで作らなかった。Rails では作って、認証認可に強くなりたい。


ライブラリ選定

devise という gem を使う。
一通り機能が揃っているらしい。

新規登録でお礼メールや、パスワードリセットなど。

https://github.com/heartcombo/devise#getting-started



devise 活用



devise をプロジェクトに入れる

https://github.com/heartcombo/devise#getting-started

bundle add devise
Enter fullscreen mode Exit fullscreen mode

bundle add で Gemfile に書き込み


devise の設定を書き込む

rails generate devise:install
Enter fullscreen mode Exit fullscreen mode

rails generate で設定を開始する。

設定値がデフォルトで、設定ファイルが生成される。

  • config/initializers/devise.rb
  • config/environments/development.rb
  • config/locales/devise.en.yml
  • config/routes.rb

など。
パスワードリセットのメールのリンク先などが設定できる。


User モデルと Migration ファイルの生成

devise を使って簡単に Model が作成できる。

rails generate devise User 
      invoke  active_record
      create    db/migrate/20230813062406_devise_create_users.rb
      create    app/models/user.rb
      invoke    rspec
Migrations are pending. To resolve this issue, run:

        bin/rails db:migrate RAILS_ENV=development
Enter fullscreen mode Exit fullscreen mode

これで models/user.rb ができる

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
end
Enter fullscreen mode Exit fullscreen mode

また、migration ファイルもできる

class AddDeviseToUsers < ActiveRecord::Migration[7.0]
  def self.up
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at
Enter fullscreen mode Exit fullscreen mode

migration ファイルにはコメントアウトされている行もある

      ## Trackable
      # t.integer  :sign_in_count, default: 0, null: false
      # t.datetime :current_sign_in_at
      # t.datetime :last_sign_in_at
      # t.string   :current_sign_in_ip
      # t.string   :last_sign_in_ip

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at
Enter fullscreen mode Exit fullscreen mode

これらのコメントアウトを外すと、最後のログインの情報を保存したり、頻繁なログイン失敗をロックしたりできる。


schema

同様に schema.rb をみると users が追加されている

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end
Enter fullscreen mode Exit fullscreen mode


既存の bankTransaction コントローラーの Rspec にログインを導入する

bankTransaction でログインを入れる


rails_helper.rb に device の読み込み設定を記載

rspec を動かす時には、rails_helper が先に動く。
なので、rails_helper に設定を書いておけば、rspec で動いてくれる。

  config.include FactoryBot::Syntax::Methods
  config.include Devise::Test::IntegrationHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :controller
Enter fullscreen mode Exit fullscreen mode

https://github.com/heartcombo/devise#test-helpers


実際に動かす

rspec --fail-fast を使うと、落ちたところで止まってくれるので便利。

class BankTransactionsController < ApplicationController

  before_action :authenticate_user!
Enter fullscreen mode Exit fullscreen mode

実装のコントローラーに認証がなかったので、コントローラーが動く前に、ログインしていなければリダイレクトに飛ばす処理を入れる

  context 'ログインしているとき' do
    before do
      user_email = "kaede0902@gmail.com"
      user = User.find_by(email: user_email) || 
        FactoryBot.create(:user, email: user_email)

      sign_in user
      # spec/factories/bank_tranksactions.rb の内容が実行される
      FactoryBot.create(:bank_transaction)
    end
Enter fullscreen mode Exit fullscreen mode

get リクエストの前に、指定のメールアドレスでユーザーを検索。

ユーザーがあればそのユーザーのインスタンスを取得。
ユーザーがなければそのユーザーを登録。

そしてそのユーザーでログイン。
ログインしている状態でコントローラーを叩く。

kaede0902@V bank_transactions_api % rspec --fail-fast

BankTransactionsController
  ログインしているとき
    GET #index
      取引明細の口座番号が正しく取得できること
      取引明細の金額が正しく取得できること
      取引明細の明細名が正しく取得できること
    POST #create
      取引データが作成できること

Finished in 0.11026 seconds (files took 1.74 seconds to load)
4 examples, 0 failures
Enter fullscreen mode Exit fullscreen mode

これでログイン認証した上で、API UT を動かせた!


伸び代

ログインしていない時の挙動をテストする。

API なのでリダイレクトにはしないほうが自然

Top comments (0)