LoginSignup
2
2

More than 1 year has passed since last update.

Rails 6.0 + Docker + MySQL5x + devise-token-auth での環境構築

Posted at

この記事の概要

  • RailsのAPIモードで認証周り作ったときに苦労したので、備忘録メモとして…。

成果物


各種バージョン

  • Ruby 2.7
  • Rails 6.0.0
  • mysql 5.7.21

前提条件

  • Dockerを使える環境が整っていること

できること

  • Rails 6.0 + Docker + MySQL5x + devise-token-auth での環境構築
  • devise-token-authを使った、サインアップ、サインイン、サインアウトができる
  • ユーザがサインインしていることを確認し、サインインしていたらuser情報を取得する

できないこと(やらないこと)

  • コピペで環境構築できるように作った記事なので、各項目の詳しい説明は割愛

環境構築手順

1. try-rails6-api のテンプレートを使用し、リポジトリを作成する

  • リポジトリ名は try-rails6-api-with-devise とする
  • 必要に応じて、 try-rails6-api と記載している箇所を自分で作成したリポジトリ名に変更する(当記事であれば try-rails6-api-with-devise に変更)

2. try-rails6-apiのREADME.md に沿って環境構築する

3. 必要なGemを追加する

Gemfile

Gemfile
・
・
・

# 認証
gem "devise"
gem "devise_token_auth"

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# ※ 疎通確認をPostmanでする場合、必要となる場合があるので追加しておく
gem 'rack-cors' 

4. ビルド&追加したGemをインストールする

docker-compose build --no-cache
docker-compose run back bundle exec rails g devise:install
docker-compose run back bundle exec rails g devise_token_auth:install User auth

5. devise_token_auth の設定

config/initializers/devise_token_auth.rb

config/initializers/devise_token_auth.rb
# frozen_string_literal: true

DeviseTokenAuth.setup do |config|
  # By default the authorization headers will change after each request. The
  # client is responsible for keeping track of the changing tokens. Change
  # this to false to prevent the Authorization header from changing after
  # each request.
  config.change_headers_on_each_request = false

  # By default, users will need to re-authenticate after 2 weeks. This setting
  # determines how long tokens will remain valid after they are issued.
  # config.token_lifespan = 2.weeks

  # Limiting the token_cost to just 4 in testing will increase the performance of
  # your test suite dramatically. The possible cost value is within range from 4
  # to 31. It is recommended to not use a value more than 10 in other environments.
  config.token_cost = Rails.env.test? ? 4 : 10

  # Sets the max number of concurrent devices per user, which is 10 by default.
  # After this limit is reached, the oldest tokens will be removed.
  # config.max_number_of_devices = 10

  # Sometimes it's necessary to make several requests to the API at the same
  # time. In this case, each request in the batch will need to share the same
  # auth token. This setting determines how far apart the requests can be while
  # still using the same auth token.
  # config.batch_request_buffer_throttle = 5.seconds

  # This route will be the prefix for all oauth2 redirect callbacks. For
  # example, using the default '/omniauth', the github oauth2 provider will
  # redirect successful authentications to '/omniauth/github/callback'
  # config.omniauth_prefix = "/omniauth"

  # By default sending current password is not needed for the password update.
  # Uncomment to enforce current_password param to be checked before all
  # attribute updates. Set it to :password if you want it to be checked only if
  # password is updated.
  # config.check_current_password_before_update = :attributes

  # By default we will use callbacks for single omniauth.
  # It depends on fields like email, provider and uid.
  # config.default_callbacks = true

  # Makes it possible to change the headers names
  config.headers_names = {:'access-token' => 'access-token',
                         :'client' => 'client',
                         :'expiry' => 'expiry',
                         :'uid' => 'uid',
                         :'token-type' => 'token-type' }

  # By default, only Bearer Token authentication is implemented out of the box.
  # If, however, you wish to integrate with legacy Devise authentication, you can
  # do so by enabling this flag. NOTE: This feature is highly experimental!
  # config.enable_standard_devise_support = false

  # By default DeviseTokenAuth will not send confirmation email, even when including
  # devise confirmable module. If you want to use devise confirmable module and
  # send email, set it to true. (This is a setting for compatibility)
  # config.send_confirmation_email = true
end

6. rack-cors の設定

rack-cors がインストールされていることを確認する

docker-compose run --rm back bundle info rack-cors

設定ファイル作成

touch config/initializers/core.rb

config/initializers/core.rb

config/initializers/core.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins "localhost:3000" # フロント側のポート番号を指定

    resource "*",
      headers: :any,
      expose: ["access-token", "expiry", "token-type", "uid", "client"],
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

7. Modelの設定

app/models/user.rb

app/models/user.rb
# frozen_string_literal: true

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
          :rememberable, :validatable
  include DeviseTokenAuth::Concerns::User
end

8. Controllerの設定

(01) Registrations Controller

コントローラ作成
docker-compose run back rails g controller v1/registrations --no-assets --no-helper
app/controllers/v1/registrations_controller.rb
app/controllers/v1/registrations_controller.rb
module V1
  class RegistrationsController < DeviseTokenAuth::RegistrationsController
    private
      def sign_up_params
        params.permit(:email, :password, :password_confirmation, :name)
      end
  end
end

(02) Users Controller

コントローラ作成
docker-compose run back rails g controller v1/users --no-assets --no-helper
app/controllers/v1/users_controller.rb
app/controllers/v1/users_controller.rb
module V1
  class UsersController < ApplicationController

    # Sign inしてないと以下のMethodは実行できない
    before_action :authenticate_v1_user!

    # 全件検索
    def index
      user = User.all
      if user
        render json: { user: user}, status: :ok
      else
        render user
      end
    end

  end
end

(03) Application Controller

app/controllers/application_controller.rb
app/controllers/application_controller.rb
class ApplicationController < ActionController::API
  include DeviseTokenAuth::Concerns::SetUserByToken
  rescue_from ActiveRecord::RecordNotFound, with: :render_404
  before_action :configure_permitted_parameters, if: :devise_controller?

  def render_404
    render status: 404, json: { message: "record not found." }
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end

9. Routingの設定

config/routes.rb

config/routes.rb
Rails.application.routes.draw do
  mount_devise_token_auth_for 'User', at: 'auth'
  namespace :v1, defaults: { format: :json } do
    get :healthcheck, to: 'sessions#healthcheck'
    mount_devise_token_auth_for 'User', at: 'auth', controllers: {
      registrations: 'v1/registrations',
      sessions: "devise_token_auth/sessions"
    }
    resources :users
  end
end

10. マイグレーション実行

docker-compose run --rm back  bundle exec rake db:migrate

疎通確認

  • Postmanを使用

1. コンテナ起動

docker-compose up

2. サインアップ

URL

[POST] http://localhost:4000/v1/auth

Body: raw(JSON)

{"email": "sample@test.com", "password": "xxxxxxxx", "name": "サンプル 太郎"}

3. サインイン

URL

[POST] http://localhost:4000/v1/auth/sign_in

Body: raw(JSON)

{"email": "sample@test.com", "password": "xxxxxxxx"}

4. サインアウト

URL

[DELETE] http://localhost:4000/v1/auth/sign_out

Headers

  • サインインで取得した、以下の項目を設定する
    • access-token
    • uid
    • client
    • expiry
    • content-type
    • token-type

5. ユーザ情報取得(サインインしていないと取得できない)

URL

[GET] http://localhost:4000/v1/users

Headers

  • サインインで取得した、以下の項目を設定する
    • access-token
    • uid
    • client
    • expiry
    • content-type
    • token-type
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2