概要
devise とその JWT 用のプラグインである devise-jwt を使って Rails6 に JWT 認証を実装します。
device を使わない JWT 認証の API の実装はこちらに別の記事があります。
Ruby 2.6.5
Rails 6.0.2.1
Devise 4.7.1
Device::JWT 0.6.0
Rails プロジェクトの作成
Rails の新しいプロジェクトを作成して、必要な gem をインストールします。
rails new devise-jwt-sample --api
cd devise-jwt-sample
Gemfile に以下を追記します。
# ...
gem 'devise'
gem 'devise-jwt'
gem 'dry-configurable', '~> 0.9.0'
そして、bundle install
します。
dry-configurable
はバージョン0.9.0
でないと現時点でエラーが出てしまうので入れています。
Devise のセットアップ
ここから Device の設定を行なっていきます。
まずはモデルの作成から。
bin/rails g devise:install
bin/rails g devise user
マイグレーションファイルが作成されるので、JWT で使うカラムを追加します。
def change
create_table :users do |t|
# ...
t.string :jti, null: false
end
# ...
add_index :users, :jti, unique: true
end
全て終わったらbin/rails db:migrate
します。
Device::JWT のセットアップ
次に JWT の設定を行います。
config/initializers/devise.rb
から JWT の署名に使う秘密鍵を設定します。
Devise.setup do |config|
# ...
config.jwt do |jwt|
jwt.secret = Rails.application.credentials.secret_key_base
end
end
User モデルを編集します。
class User < ApplicationRecord
include Devise::JWT::RevocationStrategies::JTIMatcher
devise :database_authenticatable,
:jwt_authenticatable, jwt_revocation_strategy: self
end
動作確認
すべての準備ができたので動作確認します。
適当なユーザーを作ってログインしてみます。
bin/rails r 'User.create(email: "test@example.com", password: "password")'
curl -D - -o /dev/null http://localhost:3000/users/sign_in -H 'content-type: application/json' -d '{"user": {"email": "test@example.com", "password": "password"}}'
以下のような返答があれば成功です。
閲覧に認証が必要なリソースへはAuthorization: Bearer eyJhbGc...
の箇所をヘッダーへ入れてリクエストすれば OK です。
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Location: /
Content-Type: text/plain; charset=utf-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNzk0MmY0ZC1hYTMxLTRjNzEtYmFhOC0xMzUxMzgyY2E3OWYiLCJzdWIiOiIxIiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNTgyMjc0OTc4LCJleHAiOjE1ODIyNzg1Nzh9.egm1mzjd6pqc9ZM04aZEqTdM0E-d_5OUkL5WjVoAZro
ETag: W/"36a9e7f1c95b82ffb99743e0c5c4ce95"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 125b3788-bfed-4bad-a699-03974e70ea6d
X-Runtime: 0.175217
Transfer-Encoding: chunked
おしまい