はじめに
こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
本日は、RSpec のリクエストテストでどうしても 403 Forbidden
エラーが発生してしまう問題に直面しました。 いろいろ模索していたところ、同じ課題にぶつかった方のブログに出会い、その方法を参考に無事解決できました。
この記事では、私と同じようにこの問題に悩む方のために、解決までの経緯と対処法を共有します。 参考にさせていただいた以下の記事に深く感謝いたします。
開発環境(※本記事ではここが重要です)
- Docker(docker-compose.yml)
どのようなバグだったのか
以下は、ログイン処理が正しく行えるかどうかをテストするためのコードです。
# spec/requests/user_sessions_spec.rb
RSpec.describe 'User Sessions', type: :request do
let(:user) { create(:user) }
describe 'POST /api/v1/auth/sign_in' do
it 'successfully logs in with valid credentials' do
auth_token = sign_in(user)
expect(response).to have_http_status(:success)
expect(response.headers).to include('access-token', 'client', 'uid', 'expiry', 'token-type')
end
end
end
bundle exec rspec
を実行しても、結果は 403 Forbidden
。
response
をデバッグして調査したところ、DNS リバインディング対策が原因であることが判明しました。 (この問題を通じて、DNS リバインディングという仕組みも学べました)
Rails 6 以降では、開発環境(development
)において DNS リバインディング対策がデフォルトで有効になっています。
rails_helper.rb
を確認すると、以下の記述がありました:
ENV['RAILS_ENV'] ||= 'test'
一見問題なさそうに見えますが、Docker の環境変数を確認したところ、
# docker-compose.yml
version: '3.8'
services:
backend:
build:
context: ./backend
volumes:
- ./backend:/app
- bundle-volume:/usr/local/bundle
environment:
BINDING: 0.0.0.0
RAILS_ENV: development # ← 初期値が development になっている!
つまり、テスト環境であるべきなのに、開発環境 (``********) としてテストが実行されていたことが原因だったのです。
開発環境では config.hosts
に 127.0.0.1
以外のアクセスを許可しないため、RSpec のリクエストが弾かれていました。
解決策
RAILS_ENV
を test
に設定するだけで OK です。
ENV['RAILS_ENV'] = 'test'
まとめ
-
403 Forbidden
が RSpec のリクエストテストで出たら、まずRAILS_ENV
を疑おう。 - Docker + Rails API 環境では、
docker-compose.yml
の環境変数設定に注意。 - テスト時は必ず
RAILS_ENV=test
に設定すること。 - 原因は DNS リバインディング対策が development 環境で有効になっているため。