認証をバイパスするルートを作成する方法はありますか。
これはサードパーティのサービスとの統合に使用されます。
要件は、サービスに URL を提供することです(ヘッダーやペイロードのいずれもサポートされていません)。
以前は “?api_key=…&api_username=” を追加することで可能でしたが、現在は削除されています。
Discourse インスタンスは当社でホストされています。
認証をバイパスするルートを作成する方法はありますか。
これはサードパーティのサービスとの統合に使用されます。
要件は、サービスに URL を提供することです(ヘッダーやペイロードのいずれもサポートされていません)。
以前は “?api_key=…&api_username=” を追加することで可能でしたが、現在は削除されています。
Discourse インスタンスは当社でホストされています。
カスタムプラグインを作成して、ペイロードを受け取り、それに基づいて処理を行うルートを設定する必要があります。ただし、ユーザーを認証できないため、ペイロード自体を認証する方法が必要になる点にご注意ください。
私のルールは、匿名アカウントを許可しないことです。そのため、プラグインのルートにアクセスできません。このシナリオに対応するルートを生成する方法が必要です。
例えば、
# デフォルトの Rails 3.2 は、空のセッションでリクエストを通過させます # ここではより厳格に対応し、セッションと current_user を null 化 # その後、CSRF 例外を発生させます def handle_unverified_request # 注: API キーは秘密であり、これが無効であれば CSRF トークンの必要性はなくなります unless is_api? || is_user_api? super clear_current_user render plain: "[\"BAD CSRF\"]", status: 403 end end
このフロー、あるいは認証の全体フローにおいて、パラメータ経由で受け取ったコントローラとアクション(ルート呼び出し時に自動的に設定される)がすべてのチェックをバイパスしてルートを実行できるように通知する仕組みが必要です。
すべての仕組みを完全に理解しているわけではありませんが、匿名アクセスオプションが存在する以上、実現方法はあるはずです。
これにより、必要に応じてペイロードを暗号化できるだけでなく、システムへの一般的な情報更新にも役立ちます。
プラグインを使用して、新しいルートDiscoursePluginRegistry.api_parameter_routesに追加することで、API 認証情報をクエリパラメータとして引き続き渡すことができます:
また、このサイトがログイン必須の場合、カスタムコントローラーに以下の行も追加する必要があります。
skip_before_action :redirect_to_login_if_required
はい。そのメソッドをオーバーライドしてアクションをスキップしてください。成功したら、皆さんにお知らせします。
# デフォルトでは、API 認証情報を送信するヘッダーのみを許可します
# ただし、一部のシナリオでは URL パラメータ経由で送信することが不可欠なため
# いくつかの例外を追加する必要があります
def api_parameter_allowed?
request_method = @env["REQUEST_METHOD"]&.downcase&.to_sym
request_format = @env['action_dispatch.request.formats']&.first&.symbol
path_params = @env['action_dispatch.request.path_parameters']
request_route = "#{path_params[:controller]}##{path_params[:action]}" if path_params
if 'm_exposed#endpoint' == request_route && request_method == 'get'
puts 'Allowed'
return true
end
PARAMETER_API_PATTERNS.any? do |p|
(p[:method] == "*" || Array(p[:method]).include?(request_method)) &&
(p[:format] == "*" || Array(p[:format]).include?(request_format)) &&
(p[:route] == "*" || Array(p[:route]).include?(request_route))
end
end
これは将来の git ダーフィスを最小限に抑えるために行いました。
また、私のコントローラー:
# frozen_string_literal: true
class MExposedController < ::ApplicationController
skip_before_action :redirect_to_login_if_required, raise: false
def endpoint
render json: { state: "hello world" }
end
end
requires_login をコントローラーに追加すれば解決すると思います。例については、app/controllers 内の他のコントローラーもご覧ください。
うまくいかなかったようですね ![]()
class MExposedController < ::ApplicationController
requires_login
skip_before_action :redirect_to_login_if_required, raise: false
403 Forbidden で完了しました
{"errors":["その操作を行うにはログインが必要です。"],"error_type":"not_logged_in"}
これはプラグイン内で宣言されています。
API 認証情報をクエリパラメータ経由で渡しましたか?もしそうなら、API 認証情報をクエリパラメータで許可するためのバイパスに、そのルートが正しく追加されていない可能性があります。バイパスのロジックをデバッグして、ルートが追加されたかどうかを確認する必要があります。
さて、動作して requires_login なしですべてをバイパスしています。やり方を投稿しました。 Hmm..
認証なしではしか動作しないようです。でも、少なくとも最初の問題は解決しました。