Gibt es eine Möglichkeit, eine Route zu erstellen, die die Authentifizierung umgeht?
Dies dient der Integration mit Diensten von Drittanbietern.
Die Anforderung besteht darin, dem Dienst eine URL bereitzustellen (Header oder Payloads jeglicher Art werden nicht unterstützt).
Früher war dies möglich, indem man “?api_key=…&api_username=” anhängte, aber diese Option existiert nun nicht mehr.
Du benötigst ein benutzerdefiniertes Plugin, das eine Route erstellt, die eine Nutzdatenübertragung (Payload) entgegennehmen und darauf reagieren kann. Beachte bitte, dass du, da du den Benutzer nicht authentifizieren kannst, möglicherweise eine Methode benötigst, um die Nutzdaten zu authentifizieren.
Meine Regel lautet: keine anonymen Konten. Daher kann ich nicht auf die Plugin-Routen zugreifen. Was ich benötige, ist eine Möglichkeit, für diesen Szenario eine Route zu erstellen.
Zum Beispiel:
# Standardmäßig lässt Rails 3.2 die Anfrage mit einer leeren Sitzung durch
# wir sind hier pedantischer und setzen die Sitzung / current_user auf null
# und werfen dann eine CSRF-Ausnahme
def handle_unverified_request
# HINWEIS: Der API-Schlüssel ist geheim; seine Existenz macht ein CSRF-Token überflüssig
unless is_api? || is_user_api?
super
clear_current_user
render plain: "[\"BAD CSRF\"]", status: 403
end
end
Eine Möglichkeit, während dieses Ablaufs oder des gesamten Authentifizierungsprozesses zu benachrichtigen, dass ein Controller und eine Aktion, die über Parameter empfangen werden (die automatisch gesetzt werden, wenn Sie eine Route aufrufen), alles umgehen und die Route ausführen können.
Ich bin mir nicht vollständig darüber im Klaren, wie alles funktioniert, aber da es eine Option für anonymen Zugriff gibt, bin ich sicher, dass es eine Möglichkeit gibt, dies zu realisieren.
Dies würde es ermöglichen, dass Nutzer die Nutzlast bei Bedarf verschlüsseln können, aber für das Aktualisieren des Systems mit allgemeinen Informationen wäre es nützlich.
Über ein Plugin können Sie Ihre neue Route zu DiscoursePluginRegistry.api_parameter_routes hinzufügen, sodass Sie weiterhin API-Anmeldeinformationen über Abfrageparameter übergeben können:
# Standardmäßig erlauben wir nur Header für das Senden von API-Anmeldeinformationen.
# In einigen Szenarien ist es jedoch unerlässlich, diese über URL-Parameter zu senden,
# daher müssen wir einige Ausnahmen hinzufügen.
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 'Erlaubt'
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
Ich habe dies nur getan, um die Git-Diffs für die Zukunft zu minimieren.
Außerdem mein Controller:
# 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
Jetzt prüft der Endpunkt also weder Parameter noch Header-Anmeldedaten.
Wie stelle ich sicher, dass er den bereitgestellten API-Schlüssel prüft und nur Zugriff gewährt, wenn er gültig ist? (So wie es früher funktioniert hat)
Ich glaube, das Hinzufügen von requires_login zu deinem Controller wird den Trick machen. Schau dir einige der anderen Controller in app/controllers an, um Beispiele zu finden.
Und du hast deine API-Anmeldedaten über Query-Parameter übergeben? Wenn ja, bedeutet das, dass deine Route wahrscheinlich nicht korrekt zur Umgehung hinzugefügt wurde, um API-Anmeldedaten in Query-Parametern zuzulassen. Möglicherweise musst du die Umgehungslogik debuggen und prüfen, ob deine Route jemals hinzugefügt wurde.