概要
Railsでdevise_token_auth
を使用して認証機構を実装しております。
Rspecを利用してテストを書いている際に、テスト内でトークン認証をさせるのに手間取ったので
備忘録としてアウトプットしたいと思います。
方法
ここでは、devise_token_auth
を使用してトークン認証をしている場合と、
devise
を使用してトークンを使わない認証の場合に分けて記載します。
使用例としてはログインしたユーザーが投稿を作成するというテストを考えていきます。
なおここからは認証のやり方を示すことに重点を置いているためすべて簡易的にコードを記載していきます。
deviseを使用した場合
通常devise
を使用した場合はsign_in
というヘルパーメソッドを使用してテスト内でログイン認証を行います。
まず、下記の投稿に関するcontrollerがあるとします。
またコード中に出てくるauthenticated_user!
、current_user
、sign_in
などはdeviseを導入すると
使用できるヘルパーメソッドです。
使用方法を詳しく確認したい場合は下記をご確認ください。
devise github
controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :authenticated_user!, only: [:create]
def create
# userモデルとpostモデル間での関連付けはされていると仮定
current_user.posts.create(params[:post]) #本来はストロングパラメーターを使用してrequestのパラメーターを制限すべきです
end
end
spec/requests/posts_spec.rb
#省略
describe 'POST /create' do
let!(:user) { { name: 'example_user', email: 'example@example.com', password: 'passward' } }
let(:post_params) { { content: 'example_content' } }
before do
sign_in user
post posts_path, params: { post: post_params }
end
it 'ステータスコード200が返ってくる' do
expect(response.status).to eq 200
end
end
<備考>
下記のように__rails_helper.rb__にてヘルパーをincludeするとrequest spec内でsign_in
などのヘルパーが使用できます。
spec/rails_helper.rb
RSpec.configure do |config|
# 省略
config.include Devise::Test::IntegrationHelpers, type: :request
end
以上でdeviseを使ったログイン認証をする事ができます。
devise_token_authを使用してトークン認証している場合
devise_token_authの基本使用の仕方はdeviseとほぼ同じです。
しかしトークン認証を行っているので、deviseを使用したときのようにただヘルパーメソッドのsign_in
を使って
ユーザーをログインさせるだけでは認証ができません。
deviseの場合と同じようにしようとすると、認証エラーで401が返ってきます。
controllers/posts_contorller.rb
class PostsController < ApplicationController
before_action :authenticated_user!, only: [:create]
def create
# userモデルとpostモデル間での関連付けはされていると仮定
current_user.posts.create(params[:post]) # 本来はストロングパラメーターを使用してrequestのパラメーターを制限すべき
end
end
deviseのヘルパーメソッドsign_in
ではトークン認証できないので新たにヘルパーメソッドを作成します。
spec/support/authorization_spec.rb
module AuthorizationHelper
def sign_in(user)
post posts_path, params: { email: user.email, password: user.password }
# レスポンスのHeadersからトークン認証に必要な要素を抜き出して返す処理
response.headers.slice('client', 'uid', 'token-type', 'access-token')
end
end
rails_helper.rb
RSpec.configure do |config|
# 省略
config.include AuthorizationHelper, type: :request
end
spec/requests/posts_spec.rb
#省略
describe 'POST /create' do
let!(:user) { { name: 'example_user', email: 'example@example.com', password: 'password' } }
let(:post_params) { { content: 'example_content' } }
let(:token) { sign_in user } # 追加
before do
#sign_in user # 削除
post posts_path, params: { post: post_params }, headers: token # 追加
end
it 'ステータスコード200が返ってくる' do
expect(response.status).to eq 200
end
end
<備考>
ヘルパーメソッドを定義する場合はspec配下に__support__ディレクトリを作成しその中にファイルを記載します。
そしてrspecがそのファイルを読み込むように__rails_helper.rb__で設定を行います。
rails_helper.rb
RSpec.configure do |config|
# 省略
# デフォルトではコメントアウトされています
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
end
以上がdevise_token_authを使用していた場合のrspecにおける認証です。
参考文献
【Rspec・devise token auth】Rails APIアプリのRspecテストでユーザログイン・認証を実装する方法