最近新規で作ったRailsサービスのデプロイ作業してたら認証周りの対応が地味に面倒だったので対応メモ。
前提
- JWTで認証するREST APIを提供するRailsサービス
- Railsのバージョンは6.1.4
- AWS ECS上のコンテナで稼働
- RailsはPumaで起動してNginxとsocket通信させている
ロードバランサのヘルスチェック対応
まずデプロイしたらロードバランサ(ALB)のヘルスチェックで落ちるようになった。これは心当たりがあってrailsのconfigが原因で例えばrspecを起動する時にapplication.rbかtest.rbに以下の指定をしないと落ちる
config.hosts << "www.example.com"
ので本番環境もconfig.hostsの指定をしてないせいで、ロードバランサからのリクエストを拒否してしまってたのが原因とは気づいたけど、これどうやって許可するのかで迷った。
とりあえずconfig.host.clear
と設定してしまえば通るんだけどなんか違う気がする。。
で、調べたらNginxでヘッダに許可するhostを指定する方法があってこれが良さそうだったのでこの通りに対応して通した。
Rails6のActionDispatch::HostAuthorizationとELBのヘルスチェックの共存 - Qiita
Railsのログ出力設定ではまる
これでヘルスチェックが通ってECSが動いたんだけど、その後適当なJSON投げて動作確認しようとしたら401が返ってきて通らない。CloudwatchはRailsとNginxでそれぞれロググループを作っていたんだけど、Nginx側のロググループにのみ401エラーが出ていてRails側には出力が何もない。
ってことはNginxの認証で落ちていてRailsに届いてないのでは??と思ってNginxの設定ファイルを見返したけどどう見ても問題なさそう。
それで試しにRailsのJWTの認証外してみたら通った。結局JWTがHTTPリクエストのAuthorizationのHeaderの鍵が間違っていたのが原因だったらしい。
じゃなんでRailsのログがCloudwatchに出てないんだ??と思って調べてたらconfigの設定でログが標準出力に出ていなかったのが原因だった。
config/environments/production.rb
if ENV["RAILS_LOG_TO_STDOUT"].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) end