複数のサブドメインを使用したRailsアプリの構築
今日の投稿では、複数のサブドメインをサポートできるRailsアプリを構築する方法を学びます。ゲームのウェブサイトfunkygames.co
があるとしましょう。 app.funkygames.co
などの複数のサブドメインをサポートしたい 、api.funkygames.co
、およびdev.funkygames.co
単一のRailsアプリケーションで。すべてのサブドメインに対して適切な認証が実行され、重複するルートがないことを確認する必要があります。
Railsの強力なルーティング構造を使用して、アプリケーションで複数のサブドメインをサポートします。また、ローカルでサブドメインを設定し、複数のサブドメインのテストを作成します。
前提条件
この投稿では、Railsアプリを指すようにすべてのサブドメインに適切なDNSレコードを設定していることを前提としています。この投稿では、Rails側のみを扱います。
複数のサブドメインの処理
Railsはroutes.rb
を使用します 着信要求を処理し、それらを特定のコントローラーアクションにマップするファイル。些細なアプリでは、routes.rb
のすべてのマッピング 次のように、ルートをコントローラーアクションにマップします。
get '/games/:id', to: 'games#show'
このアプローチでは、routes.rb
で定義されているすべてのエンドポイント fileはすべてのサブドメインに適用できます。つまり、app.funkygames.co/games/1
また、api.funkygames.co/games/1
このルートで処理されます。ただし、app
からのリクエストのみが必要です。 このルートで処理されるサブドメイン。 api
サブドメインはAPIルートにのみ使用されます。ルートにいくつかのルールを追加して、着信リクエストに対して特定のルールが満たされた場合にのみそれらが処理されるようにします。
Railsルーティングはconstraints
を提供します 指定されたルートに追加のルールを指定できるヘルパーメソッド。
get '/games/:id', to: 'games#show', constraints: { subdomain: 'app' }
これにより、リクエストがapp.funkygames.co/games/1
から送信された場合に確実になります 、GamesController's
によって処理されます アクションを表示します。 app
以外の他のサブドメインからのリクエスト このルートでは処理されません。
constraints
を定義するのは非常に面倒になります すべてのルートでこのようになります。
get '/games/:id', to: 'games#show', constraints: { subdomain: 'app' }
get '/games/list', to: 'games#list', constraints: { subdomain: 'app' }
post '/games/start', to: 'games#start', constraints: { subdomain: 'app' }
constraints
のブロック形式を使用できます 単一のサブドメインに複数のルートを定義するヘルパー。
constraints subdomain: 'app' do
get '/games/:id', to: 'games#show'
get '/games/list', to: 'games#list'
post '/games/start', to: 'games#start'
end
複数のサブドメインのルートを定義するには、複数のconstraints
を追加するだけです。 routes.rb
のブロック ファイル。
constraints subdomain: 'app' do
...
end
constraints subdomain: 'api' do
...
end
constraints subdomain: 'dev' do
...
end
フードの下
Railsルーティングはリクエスト制約とセグメント制約を提供します。セグメント制約は要求パスにルールを追加しますが、要求制約は着信要求に条件を追加します。リクエスト制約のハッシュキーは、Request
のメソッドである必要があります 文字列を返すオブジェクトであり、値は期待値である必要があります。
constraints subdomain: 'app' do
...
end
上記の場合、subdomain
を使用しています Request
のメソッド オブジェクトを作成し、app
のような文字列と照合します 、api
またはdev
。
詳細については、Railsルーティングガイドを参照してください。
マルチレベルサブドメインの処理
app.staging.funkygames.co
を使用しているとしましょう 私たちのステージング環境のために。上記の設定を行っている場合、app
にヒットするはずのすべてのリクエストにすぐに気付くでしょう。 サブドメインは404を返します。さらにデバッグすると、サブドメインの制約が失敗していることがわかります。
request.subdomain #=> app.staging
サブドメインがapp
を返すことを期待していました 、ただし、代わりに、app.staging
を返します。 。もちろん、環境固有のコードを追加せずにこれを解決したいと思います。リクエストのサブドメインの解析は、config.action_dispatch.tld_length
によって管理されます。 オプション。この構成のデフォルト値は1で、基本的に1レベルのサブドメインをサポートします。 2つのレベルのサブドメインがあるため、config.action_dispatch.tld_length
の値を設定する必要があります 2に。
# config/application.rb
config.action_dispatch.tld_length = Integer(ENV['TLD_LENGTH'] || 1)
環境変数を使用して設定できるため、ステージング環境と本番環境で同じコードを使用できます。これで、ルーティング設定がapp.staging.funkygames.co
で機能します。 同様に。
セッション管理
複数のサブドメインからのリクエストを処理するようにルートが定義されたので、すべてのサブドメインの認証を処理する必要があります。これは2つの方法で行うことができます。つまり、すべてのサブドメインで同じユーザーセッションを使用できるようにするか、別々のサブドメインに別々のセッションを設定することができます。
一言で言えば認証
RailsはデフォルトでCookieを使用してユーザーセッションキーを保存します。ユーザーがログインすると、ユーザーのセッション情報が選択したセッションストアに保存され、セッションキーがブラウザにCookieとして保存されます。そのため、次にユーザーが当社のWebサイトにアクセスすると、同じセッションCookieがブラウザーからサーバーに送信され、サーバーは、受信セッションCookieのセッションが存在するかどうかに基づいて、ユーザーがログインしているかどうかを判断します。
Railsアプリでは、セッションのデフォルト構成は次のようになります。
Rails.application.config.session_store :cookie_store, key: "_funkygames_session"
キー_funkygames_session
セッションCookieの名前として使用され、その値はセッションIDになります。
Cookies入門書
デフォルトでは、Cookieはリクエストのドメインのブラウザによって設定されます。したがって、app.funkygames.co
からアプリケーションにアクセスしている場合 次に、セッションCookieがapp.funkygames.co
に対して設定されます。 。各サブドメインは独自のセッションCookieを設定するため、ユーザーセッションはデフォルトではサブドメイン間で共有されません。
異なるサブドメイン間でのセッションの共有
サブドメイン間でユーザーセッションを共有する場合は、funkygames.co
でセッションCookieを設定する必要があります ドメイン自体。すべてのサブドメインがアクセスできるようにします。これは、domain
を渡すことで実現できます。 セッションストア設定のオプション。
Rails.application.config.session_store :cookie_store, key: "_funkygames_session", domain: :all
domain
を渡すことによって :all
として 、基本的には、funkygames.co
などのアプリケーションのトップレベルドメインにセッションCookieを設定するようにRailsに指示しています。 個々のサブドメインを含む可能性のあるリクエストホストではなく。これを行うと、セッションを異なるサブドメイン間で共有できるようになります。
ドメインのリストを
domains
に渡すこともできます 複数のドメインをサポートするための配列形式のオプション。
すべてのサブドメインのCookieを適切に設定するために構成する必要があるもう1つのオプションがあります。 tld_length
です オプション。 domain: :all
を使用する場合 、このオプションは、ドメインを解析してドメインのTLDを解釈する方法を指定できます。この場合、app.funkygames.co
の場合 、tld_length
を設定する必要があります RailsがTLDをfunkygames.co
として解釈する場合は2に クッキーを設定するとき。したがって、複数のサブドメインの最終的なセッションストア構成は次のようになります。
Rails.application.config.session_store :cookie_store,
key: "_funkygames_session",
domain: :all,
tld_length: 2
tld_length
セッションストアのオプションは、config.action_dispatch.tld_length
とは異なります。 前に説明しました。
複数のサブドメインのテストの作成
ルートはサブドメイン固有であるため、テストリクエストに適切なサブドメインがない場合、リクエストの仕様または統合テストで404エラーが発生します。 Rails統合テストはhost!
を提供します テストファイル内で行われたすべてのリクエストに適切なサブドメインを設定できるヘルパー。
# Configuring subdomain in Rails integration tests
setup do
host! 'dev.example.com'
end
# # Configuring subdomain in RSpec request specs
before do
host! 'dev.example.com'
end
この後、リクエストはroutes.rb
のサブドメインルーティングに従って、コントローラーアクションに正しくルーティングされます。 ファイル。
ここではドメインは重要ではなく、テストしているコードに基づく適切なサブドメインのみが重要であることに注意してください。
開発用にローカルで複数のサブドメインを設定する
サブドメインをローカルに設定する方法は複数あります。最も簡単なのは、/etc/hosts
を編集することです。 ファイル。
127.0.0.1 dev.funkygames.local
127.0.0.1 app.funkygames.local
127.0.0.1 api.funkygames.local
これにより、サブドメインの設定がローカル環境で機能することが保証されます。サブドメインをローカルで管理するために、powなどのツールを使用することもできます。
制約ベースのサブドメインルーティングを使用したGotchas
制約ベースのサブドメインルーティングはほとんどの場合機能しますが、特定の状況では問題になる可能性があります。
外部APIの処理
サードパーティのAPIを使用して統合を構築している場合、.local
などのローカル開発TLD または.dev
許可されていません。 ngrokなどのツールを使用する必要があります。このような場合、サブドメインベースのルーティングは機能しません。特定のルートをホワイトリストに登録して、ngrok経由でもアクセスできるようにする必要があります。
サブドメインの制約外のルート
特定のルートをサブドメイン制約内に配置することはできません。典型的な例はhealthcheck
です。 またはping
エンドポイント。 Railsアプリの前でロードバランサーを使用している場合、ロードバランサーはアプリが起動しているかどうかを定期的にチェックする必要があります。 healthcheck
このような場合に使用されるエンドポイントは、ロードバランサーがリクエストホストの知識を持っていない可能性が高いため、サブドメインの制約下に置くことはできません。
ルートルートがない
Railsには特別なroot
があります 基本的にアプリケーションのデフォルトルートであるルート。他のルートのいずれもリクエストと一致しない場合は、root
ルートが使用されます。いずれかのサブドメインの下にすべてのルートがある場合、root
がない状況が発生する可能性があります。 ルートが定義されています。特定のgemは、root
の存在に依存する場合があります。 ルートを設定し、それに応じてチェックとバランスを追加する必要があります。
結論
この投稿では、構成行が非常に少ない複数のサブドメインを使用してRailsアプリをセットアップします。また、複数のサブドメインに対して効果的なテストを作成するためのヒントとともに、ローカルおよびさまざまな環境でサブドメインを設定する方法についても説明しました。 Railsが提供する配管を使用すると、複数のサブドメインを使用してRailsアプリを簡単にセットアップしてテストできます。
P.S。 Ruby Magicの投稿をマスコミから離れたらすぐに読みたい場合は、Ruby Magicニュースレターを購読して、投稿を1つも見逃さないでください。
-
Rails5でのAngularの使用
あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた
-
Photo Organizer アプリで複数の画像の名前を変更する方法
デジタル画像は、ハード ドライブを乱雑にするものです。これらの貴重な思い出は、分類して整理するのが非常に難しく、ほとんど不可能に思えることもあります。画像関連の問題のいくつかを解決するために、画像の並べ替え、重複の削除、写真の名前の一括変更に役立つ Systweak Photo Organizer があります。このガイドでは、Systweak Photo Organizer のすべてと、一度に複数の画像の名前を変更する方法について説明します。 フォト オーガナイザー アプリで複数の画像の名前を変更する手順 ステップ 1 :Systweak Photo Organizer を Microso