2016-06-26 5 views
0

Dies könnte eine akademische/philosophische Frage sein, aber angenommen, ich habe eine Ressource, in Rails, und ich bekomme localhost:3000/resources/2foobar, wird dies serviert, als ob foobar nicht da war. Während das zunächst cool ist, stellt sich die Frage, ob hinter den Kulissen etwas fehlen könnte. Ich vertraue generell Open-Source-Projekten, und Rails war lange genug für mich, um zuversichtlich zu sein, aber wäre es nicht besser, wenn wir den Parameter validieren könnten, um zu überprüfen, ob er streng numerisch ist und nicht nur mit einer Zahl beginnt? Zum Beispiel könnte ich meine show Methode wieWarum werden Anfrageparameter wie `1duh` in Rails wie` 1` behandelt?

if (Integer(params[:id]) != nil rescue false) 
    render json: @resource 
else 
    head: 400 
end 

Kann mir jemand erklären, die Gründe ändern 1duh als 1 zur Behandlung in Rails?

EDIT Beispiel Anfrage

$ curl 'localhost:3000/resources/1ds' 

Entsprechende log

Started GET "/resources/1ds" for ::1 at 2016-06-26 20:35:59 +0100 
Processing by ResourcesController#show as */* 
    Parameters: {"id"=>"1ds"} 
    Resource Load (0.3ms) SELECT `resources`.* FROM `resources` WHERE `resources`.`id` = 1 LIMIT 1 
Completed 200 OK in 9ms (Views: 0.7ms | ActiveRecord: 0.3ms) 

Locke kehrt

{"id":"1","data":"foobarsampledata"} 
+0

Ich bin mir nicht sicher, wie Sie Ihre Bedeutung von "behandelt" behandeln sollen. Können Sie das näher ausführen? "gedient" wo? Alle Protokolle zu unterstützen? Soweit ich sehen kann, können Schienen in Params ID '2foobar' übergeben werden und Ihr Controller kann es bekommen, also wo ist das" Behandeln "passiert? Also, meintest du eigentlich "localhost: 3000/resource/2foobar" oder "localhost: 3000/resourceS/2foobar"? –

+0

Ich habe ein kleines Sample in die Fragen eingefügt. Wie Sie sehen können, werde ich GET '/ resources/1ds',' 1ds' wird so übernommen und an 'Resource :: find' übergeben, was wiederum als' 1' betrachtet wird (siehe SQL-Abfrage) und gibt das Ergebnis zurück Ressource mit ID 1. Ich habe erneut versucht, '/ resources/ds1' zu beantragen und stattdessen eine 404. – Morpheu5

Antwort

2

Ok, here ist Ihre Antwort:

Wenn der Primärschlüssel eine ganze Zahl ist, erzwingt find by id seine Argumente mithilfe von to_i.

Person.find("1")  # returns the object for ID = 1 
Person.find("31-sarah") # returns the object for ID = 31 

Also, der Grund dafür ist, Ihr Primärschlüssel. Und ich denke, wenn Ihr Primärschlüssel keine ganze Zahl wäre, würde dies (Umwandlung to_i) nicht passieren.

+0

Ich sehe. Also, ich kann im Wesentlichen .to_i vertrauen, um seine Arbeit hinter den Kulissen richtig zu machen - d. H. Es gibt sehr wenig Chance einer SQL-Injektion durch .find ... – Morpheu5

+0

Sie können to_i vertrauen und finden. In der Tat können Sie "paranoid" gehen und Constraints für die ganze Zahl in Ihrer routes-Datei hinzufügen, aber ich denke, es ist ein Overkill. Um SQL-Injektionen zu vermeiden, stellen Sie sicher, dass Sie Ihre Parameter ** nicht direkt ** in Abfragebedingungsstrings und ähnliches einfügen, und Sie sollten OK sein. –