Techioz Blog

フロントエンドを使用した Rails API - 電子メール リンクをバックエンドまたはフロントエンド アプリケーションにルーティングする

概要

Rails API バックエンドと ReactJS フロントエンドがあります。私のバックエンドは、多くの場合、確認のようなリンク (メール確認など) を含むカスタムメールを送信します。

確認リンクはバックエンドを直接指すべきですか、それとも最初にフロントエンドをロードしてからバックエンドへの API 呼び出しを行うべきですか?

私が考えている代替案は次の 2 つです。

1 - メール確認リンクが直接ヒットします

backend.example.com/email_confirmations/:confirmation_token、これにより、フロントエンドの特定の成功 (エラー) ページ、frontend.example.com/email_confirmation/success(/failure) にリダイレクトされます。

バックエンドでは、フロントエンド アプリへのリダイレクトを実行するための最小限のモジュールを備えた Metal コントローラーのみが必要です。コントローラーは常にリダイレクトで応答します)。フロントエンドからさらにアクションを実行する必要がある場合、別の API エンドポイントがヒットします。

2 - 電子メール確認リンクにより、次のフロントエンドが開きます。

Frontend.example.com/email_confirmations/:confirmation_token は、backend.example.com/email_confirmations/:confirmation_token への API リクエストをトリガーします。

次に、私の (Json:api) バックエンドは、Rails APIController を使用して jsonapi 準拠の応答を作成します。

練習では何をしているのですか?

最初のシナリオにオプトインすることにしましたが、最初にフロントエンドを体系的に呼び出し/ロードするほうが合理的でしょうか?

このようなシナリオでは、バックエンド/フロントエンドをどのように接続しますか?

私は現在、受信パラメータを処理するだけの非常に単純な(メタル)コントローラを実装し、フロントエンドへのリダイレクトのみを実行します。次のようにフロントエンドを指す「URL ヘルパー」を定義したいと考えていました。

namespace :email_redirection do 
    # Controller that gets hit by email confirmation links in scenario #1
    resources :confirmations
end

namespace :frontend do
    frontend_root = Rails.configuration.frontend_host_with_http_and_port

    scope frontend_root do
      # Generation of URL Helpers for the frontend app
      resources :confirmations, only: [] do
        get 'successful'
        get 'unsuccessful'
      end
    end
end

そして、私の確認コントローラーは次のようになります

class EmailRedirection::ConfirmationsController
  def index
    svc = MyConfirmationService.new(token: params[:confirmation_token])
    if svc.confirm
      redirect_to(
        frontend_successful_confirmation_url,
        email: svc.confirmable.email
      )
      else
        redirect_to(frontend_unsuccessful_confirmation_url)
      end
    end
  end

いくつかのエラーが発生しており、おそらく URL ヘルパーは別のホスト/ポートでは使用できないと思います… (または、各呼び出しに明示的に渡す必要があります)

どうすればそれに対処できますか?また、1. が適切な選択である場合、成功/失敗時に送信するリダイレクト コードは何になりますか (3xx のみであるため)。

どちらのソリューションもバックエンド/フロントエンド間のかなりの配線が必要ですが、どのように接続するのが最善かわかりません。

注: 私のモデルは Device を使用していますが、Devic は API などにあまり優れていないためです。私はいくつかの副作用も処理する独自のconfirmationServiceを使用しています。 Devise はここでは関係ないと思います

外部 URL への Rails ルートの作成

解決策

どちらのアプローチにも長所と短所があり、どちらを選択するかは、特定の要件と好みによって異なります。それぞれのアプローチを詳しく見てみましょう。

フロントエンドとバックエンドの間でホスト/ポートが異なるために URL ヘルパーで問題が発生した場合は、URL を生成するときにホストを明示的に指定できます。 Rails では、ホスト パラメータを URL ヘルパーに渡すことでこれを実現できます。

redirect_to frontend_successful_confirmation_url(host: 'frontend.example.com', email: svc.confirmable.email)

成功するには、リダイレクトに 302 Found または 303 See Other を使用できます。失敗の場合は、4xx ステータス コード (たとえば、クライアント エラーの場合は 400 Bad Request) または 5xx ステータス コード (たとえば、サーバー エラーの場合は 500 Internal Server Error) を使用できます。