Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

複数のサブドメインを使用した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つも見逃さないでください。


  1. Rails5でのAngularの使用

    あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた

  2. Photo Organizer アプリで複数の画像の名前を変更する方法

    デジタル画像は、ハード ドライブを乱雑にするものです。これらの貴重な思い出は、分類して整理するのが非常に難しく、ほとんど不可能に思えることもあります。画像関連の問題のいくつかを解決するために、画像の並べ替え、重複の削除、写真の名前の一括変更に役立つ Systweak Photo Organizer があります。このガイドでは、Systweak Photo Organizer のすべてと、一度に複数の画像の名前を変更する方法について説明します。 フォト オーガナイザー アプリで複数の画像の名前を変更する手順 ステップ 1 :Systweak Photo Organizer を Microso