Ist diese Rails-JSON-Authentifizierungs-API (mit Devise) sicher?
Meiner Rails-app nutzt Entwickeln, die für die Authentifizierung. Es hat eine Schwester-iOS-app, und Benutzer können sich in der iOS-app mit den gleichen Anmeldeinformationen, die Sie verwenden für die web-app. Also brauche ich eine Art API für die Authentifizierung.
Viele ähnliche Fragen hier dieses tutorialaber es scheint zu sein, out-of-date, wie die token_authenticatable
Modul wurde inzwischen entfernt Erarbeiten und einige der Linien werfen Fehler. (Ich bin mit Entwickeln 3.2.2.) Ich habe versucht zu Rollen, meine eigene, basierend auf diesem tutorial (und diese eine), aber ich bin mir nicht 100% sicher drin - ich fühle mich wie es sein kann, etwas habe ich falsch verstanden oder verpasst.
Erstens, im Anschluss an die Beratung der diese gistich habe eine authentication_token
text-Attribut, um meine users
Tisch, und die folgenden user.rb
:
before_save :ensure_authentication_token
def ensure_authentication_token
if authentication_token.blank?
self.authentication_token = generate_authentication_token
end
end
private
def generate_authentication_token
loop do
token = Devise.friendly_token
break token unless User.find_by(authentication_token: token)
end
end
Dann habe ich folgende Controller:
api_controller.rb
class ApiController < ApplicationController
respond_to :json
skip_before_filter :authenticate_user!
protected
def user_params
params[:user].permit(:email, :password, :password_confirmation)
end
end
(Beachten Sie, dass meine application_controller
hat die Linie before_filter :authenticate_user!
.)
api/sessions_controller.rb
class Api::SessionsController < Devise::RegistrationsController
prepend_before_filter :require_no_authentication, :only => [:create ]
before_filter :ensure_params_exist
respond_to :json
skip_before_filter :verify_authenticity_token
def create
build_resource
resource = User.find_for_database_authentication(
email: params[:user][:email]
)
return invalid_login_attempt unless resource
if resource.valid_password?(params[:user][:password])
sign_in("user", resource)
render json: {
success: true,
auth_token: resource.authentication_token,
email: resource.email
}
return
end
invalid_login_attempt
end
def destroy
sign_out(resource_name)
end
protected
def ensure_params_exist
return unless params[:user].blank?
render json: {
success: false,
message: "missing user parameter"
}, status: 422
end
def invalid_login_attempt
warden.custom_failure!
render json: {
success: false,
message: "Error with your login or password"
}, status: 401
end
end
api/registrations_controller.rb
class Api::RegistrationsController < ApiController
skip_before_filter :verify_authenticity_token
def create
user = User.new(user_params)
if user.save
render(
json: Jbuilder.encode do |j|
j.success true
j.email user.email
j.auth_token user.authentication_token
end,
status: 201
)
return
else
warden.custom_failure!
render json: user.errors, status: 422
end
end
end
Und in config/routes.rb:
namespace :api, defaults: { format: "json" } do
devise_for :users
end
Ich bin aus meiner Tiefe ein bisschen und ich bin sicher, es gibt hier etwas, das meine Zukunft Aussehen wird, wieder auf und kriechen (gibt es normalerweise der Fall ist). Einige iffy Teile:
Erstenswerden Sie feststellen, dass Api::SessionsController
erbt von Devise::RegistrationsController
in der Erwägung, dass Api::RegistrationsController
erbt von ApiController
(ich habe auch einige andere Controller wie Api::EventsController < ApiController
die sich mit der mehr standard-REST Kram für meine anderen Modelle und haben nicht viel Kontakt mit Entwickeln.) Dies ist eine ziemlich unschöne Anordnung, aber ich konnte nicht herausfinden, ein anderer Weg, um Zugriff auf die Methoden, die ich brauche in Api::RegistrationsController
. Das tutorial habe ich im Zusammenhang mit oben hat die Linie include Devise::Controllers::InternalHelpers
aber dieses Modul scheint entfernt worden, die in neueren Versionen von Entwickeln.
Zweitens habe ich deaktiviert CSRF-Schutz mit der Linie skip_before_filter :verify_authentication_token
. Ich habe meine Zweifel, ob das eine gute Idee ist - ich sehe eine Menge von widersprüchliche oder schwer zu verstehen Beratung darüber, ob JSON-APIs sind anfällig für CSRF-Attacken - aber das hinzufügen dieser Zeile war der einzige Weg, ich könnte das verdammte Ding zu arbeiten.
Drittensmöchte ich sicherstellen, dass ich verstehe, wie die Authentifizierung funktioniert, sobald ein Benutzer angemeldet ist. Sagen, ich habe einen API-Aufruf GET /api/friends
gibt eine Liste der aktuellen Benutzer, die Freunde. Wie ich es verstehe, ist die iOS-app hätte, um die Benutzer authentication_token
aus der Datenbank (das ist ein fester Wert für jeden Benutzer, der sich niemals ändert??), dann reichen Sie es als param zusammen mit jeder Anforderung, z.B. GET /api/friends?authentication_token=abcdefgh1234
dann meine Api::FriendsController
etwas tun könnte wie User.find_by(authentication_token: params[:authentication_token])
um die current_user. Ist es wirklich so einfach, oder bin ich etwas fehlt?
Also für jeden, der es geschafft hat zu Lesen, den ganzen Weg bis zum Ende dieser Mammut-Frage, vielen Dank für Ihre Zeit! Zusammenfassend:
- Ist dieses login system sicher? Oder gibt es so etwas habe ich übersehen oder missverstanden, z.B. wenn es um CSRF-Angriffe?
- Ist mein Verständnis für die Anforderungen authentifizieren, wenn Benutzer angemeldet sind, richtig? (Siehe "drittens..." oben).
- Gibt es eine Möglichkeit, diesen code bereinigt werden können oder schöner gemacht? Besonders das hässliche design von one controller Erben von
Devise::RegistrationsController
und die anderen vonApiController
.
Dank!
InformationsquelleAutor der Frage GMA | 2013-12-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Sie nicht deaktivieren möchten, CSRF, ich habe gelesen, dass die Leute denken, es nicht gelten zu JSON-APIs für einige Grund, aber das ist ein Missverständnis. Halten Sie es aktiviert, werden Sie wollen, um einige änderungen:
dort auf server-Seite hinzufügen after_filter zu Ihren Sitzungen controller:
Dies generiert ein token, steckte es in Ihre Sitzung und kopieren Sie Sie im response-header für ausgewählte Aktionen.
client-Seite (iOS) müssen Sie sicherstellen, dass zwei Dinge sind an Ort und Stelle.
Ihr Kunde braucht, um zu Scannen alle server-Antworten für diese Kopf-und behalten es, wenn es weitergegeben wird.
endlich, Ihr Kunde braucht, um dieses token an alle "nicht" - Anfragen sendet:
Letzte Stück des Puzzles ist es, zu verstehen, dass bei der Anmeldung zu erarbeiten, das zwei nachfolgenden Sitzungen/csrf-Token verwendet werden. Eine Anmeldung fließen würde wie folgt Aussehen:
InformationsquelleAutor der Antwort beno1604
Deinem Beispiel scheint zu imitieren, die code von die Entwickeln blog - https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
Wie erwähnt, in diesem post, du machst es ähnlich zu option 1, die Sie sagen, ist die unsichere option. Ich denke, der Schlüssel ist, dass Sie nicht wollen, einfach einen reset der token zur Authentifizierung jedes mal, wenn der Benutzer gespeichert wird. Ich denke, dass das token erstellt werden soll, die explizit (durch eine Art TokenController in der API) und ablaufen soll in regelmäßigen Abständen.
Wirst du bemerken, dass ich sagen 'ich glaube', da (soweit ich das sagen kann) niemand hat mehr Informationen dazu.
InformationsquelleAutor der Antwort Jaco Pretorius
Den top 10 der häufigsten vulnerablites in web-Anwendungen sind dokumentiert in der OWASP Top 10. Dieser Frage erwähnt, dass Cross-Site Request Forgery(CSRF) Schutz deaktiviert wurde, und CSRF ist auf der OWASDP Top 10. In kurzen, CSRF-Angriffe verwendet wird, die von Angreifern zum ausführen von Aktionen, wie einen authentifizierten Benutzer. Deaktivieren der CSRF-Schutz führt zu einem hohen Risiko Sicherheitslücken in einer Anwendung, und untergräbt den Zweck, eine sichere Authentifizierung-system. Ist es wahrscheinlich, dass der CSRF-Schutz war ein Fehlschlag, weil der Kunde versäumt, übergeben Sie die CSRF-Synchronisations-token.
Lesen Sie die gesamte OWASP top 10, wenn das nicht geschieht, ist äußerst gefährliche. Achten Sie auf Broken Authentication und Session Managementschauen Sie sich auch die Session Management Cheat Sheet.
InformationsquelleAutor der Antwort rook