Grundlegende HTTP-Authentifizierung, einschließlich JSON nicht in Header? (Backbone.js Rails zu Server)
-
11-10-2019 - |
Frage
Ich verwende Backbone.js ein reines JS Front-End für meine Schienen zu schaffen App einen JSON-API verwenden.
Die Backbone.js Modell URL sieht wie folgt aus:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://localhost:3000/medication_options'
});
arbeitet CRUD fein mit diesem. Es Anfragen auf meinen Server mit einem „application / JSON“ Inhaltstyp zu senden.
Aber ich brauchte Authentifizierung für die API hinzuzufügen und meine Rails-Anwendung verwendet Authlogic so fügte ich diese:
before_filter :require_user
def require_http_auth_user
return true if current_user
authenticate_or_request_with_http_basic do |email, password|
email = email.gsub("_at_", "@") if email.include?("_at_")
if @current_user = User.find_by_email(email)
@current_user.valid_password?(password)
else
false
end
end
end
Und eine typische CRUD Methode in Schienen wie folgt aussieht:
def update
@medication_option = MedicationOption.find(params[:id])
if @medication_option.update_attributes(params[:medication_option])
flash[:notice] = "Successfully updated medication."
end
respond_with @medication_option
end
Also in meinem Backbone.js Modell hinzugefügt I "username: password" zur url:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://username:password@localhost:3000/medication_options'
});
Die Authentifizierung in Ordnung mit den entsprechenden Anmeldeinformationen funktioniert, aber aus irgendeinem Grunde alle der Backbone.js Anforderungen durch den Rails-Server als HTML interpretiert werden anstelle von JSON.
Aus irgendeinem Grunde während einer Basis HTTP-Authentifizierung, der JSON-Header in der Mischung verloren geht.
Also, wenn ich hinzufügen explizit „.json“ an das Ende der URL wie folgt aus:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://username:password@localhost:3000/medication_options.json'
});
kann ich grundlegende GET-Anfragen an die Arbeit.
Aber wenn ich tun CRUD es nicht funktioniert, weil es die ID an das Ende der URL anhängt, so dass es Fehler:
ActionController::RoutingError (No route matches "/medication_options.json/41516")
Also ich bin nicht sicher, wo man von hier geht.
Lösung
Ihre .json sollten am Ende der URL immer als json interpretiert werden:
/medication_options/41516.json
Sie können die Modell-URL sowie die Sammlung URL bearbeiten, wenn notwendig, um die json an der richtigen Stelle zu setzen.
Das eigentliche Problem ist, warum es nicht als json in erster Linie verarbeitet bekommen. Wenn Sie mit Schienen 3 haben Sie:
respond_to :js
oder
respond_to :json
Ihre respond_with anzupassen und stellen Sie sicher, dass Ihr Controller diese Art von Format akzeptiert (sonst würde das Rückschiene 406 Fehler in der Standardeinstellung)?
Andere Tipps
Ich habe noch nie Document.js, aber in der Suche durch die Dokumentation verwendet es scheint, dass Sie url
außer Kraft setzen können und geben das Ergebnis einer Funktion, anstatt ihm einen wörtlichen Zeichenfolge-Wert zu geben. Könnten Sie den .json
bis zum Ende der URL-Zeichenfolge auf diese Weise hinzufügen?
Versuchen Sie etwas wie folgt aus:
_.extend(Medication,
{extension:'.json',
url:function() {
var base = getUrl(this.collection);
if (this.isNew()) return base + this.extension;
return (base + (base.charAt(base.length - 1) == '/' ? '' : '/')
+ this.id + this.extension);
}
});