2013-08-26 11 views
10

Ich habe eine Flask-App, die als REST-API-Backend dient. Ich möchte Token-basierte Authentifizierung für das Backend implementieren, aber um das zu tun, muss ich das Benutzer-Token abrufen. Die Flask-Security-Dokumentation besagt eindeutig, dass zum Abrufen des Tokens ein HTTP-POST mit den Authentifizierungsdetails als JSON-Daten zum Authentifizierungsendpunkt ausgeführt werden muss. Leider verstehe ich nicht, wie ich das CSRF-Token abrufen kann, das zur Ausführung einer solchen Anfrage benötigt wird.Flask-Security CSRF-Token

Wenn ich die Anmeldeseite/Vorlage verwende, die mit der Erweiterung geliefert wurde, wird das CSRF-Token an den Client in dem ausgeblendeten Feld im Formular übergeben. Die Frage lautet:

Wie kann ich das CSRF-Token abrufen, ohne auf die Anmeldeseite zuzugreifen und diese zu analysieren, z. B. aus einer angularJS-App mit $ http-Methoden oder einer mobilen App?

Offensichtlich konnte ich vermeiden Flask-Sicherheit zu verwenden und die Stücke selbst zu implementieren, aber ich bin relativ unerfahren mit Webapps und ich fühle mich, dass ich das in die falsche Richtung gehen könnte.

+0

Wie hast du das am Ende gemacht? – kyrre

+0

Ich habe die Sicherheitsebene selbst implementiert. Tut mir leid, ich habe keine bessere Antwort für dich. – Jacopo

+0

Beachten Sie, dass es keine sichere Möglichkeit gibt, die Tokens in angularjs zu speichern, siehe z. [hier] (https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/). Die sichere Option besteht darin, den Server das Token in einem HTTP-Only-Cookie speichern zu lassen und den CSRF-Schutz zu aktivieren. Wenn Sie nur angularjs brauchen, können Sie auch einfach die Session (+ anti-CSRF) verwenden. – Adversus

Antwort

2

Ich habe nicht getestet, dass dies funktioniert, aber aus der kurzen Überprüfung des source code scheint es, dass Sie eine GET-Anfrage an die Login-URL mit dem Inhaltstyp application/json senden müssen. Flask-Security antwortet auf diese Anfrage mit einer JSON-Version des Anmeldeformulars und mit dem Token. Sobald Sie das Token haben, können Sie die POST-Anfrage senden.

+0

Danke, dass Sie auf die richtige Straße gesetzt haben. Zusätzlich zu einer GET-Anfrage muss ich einige JSON-Daten mit der Anfrage übergeben, ansonsten ist "request.json" in Flask leer und die Methode "_render_json" wird nicht ausgelöst. Leider führt dies jedoch zu einem Fehler in Zeile 45 der verknüpften Quelle, da das Formular kein Benutzerattribut enthält. Aber wenn ich kurz auf den Code schaue, denke ich, dass das Benutzerattribut während der Validierung gesetzt werden sollte, aber nicht für diese Anfrage. Ich muss weiter graben. Danke nochmal – Jacopo

+0

OK Ich habe den Fehler herausgefunden. Die 'validate_on_submit' Methode von Flask-WTF prüft zuerst nach 'is_submitted', was für eine GET-Anfrage falsch ist. Dies verhindert, dass die 'validate'-Methode aufgerufen und das Attribut' user 'im Formular zugewiesen wird. Wenn Sie jedoch die Methode 'validate' manuell aufrufen, wird der Fehler 'CSRF token missing' ausgegeben, und wir sind wieder am Start. – Jacopo

4

hatte ich einen ähnlichen Anwendungsfall und beenden es unter folgendem Beispiel aus dem Kolben-WTF docs Lösung: https://flask-wtf.readthedocs.org/en/latest/csrf.html#ajax über CsrfProtect(app)

So von CSRF Schutz des App, die csrf_token() in allen Vorlagen zur Verfügung steht. Dann können Sie diese leicht über einen Script-Tag zur Verfügung stellen:

<script type="text/javascript"> 
    var csrftoken = "{{ csrf_token() }}" 
</script> 

nun das Token auf Ihre Post-Daten für den Kolben-Sicherheit/Login Endpunkt hinzufügen.

+2

Danke für die Antwort, aber am Ende habe ich meine eigene Benutzerverwaltungslösung implementiert. Dies funktioniert auch nur, wenn Sie die Seiten mit der Flask-App bedienen und die Vorlage mit Jinja rendern. Wenn Sie die Flask-App nur für das Backend (REST-API) verwenden und das Frontend mit anderen Methoden geliefert wird, müssen Sie einen API-Endpunkt bereitstellen, um das Token abzurufen und es in der json-Antwort zu rendern. Ich bin mir nicht sicher, wie das funktionieren würde, ich werde es vielleicht versuchen. – Jacopo

0

[Schreiben als eine Antwort, da ich nicht genug Ruf Kommentar]

ich genau in gleiche Problem wie Jacopo ausgeführt haben, dass - request.json leer ist und somit get_auth_token() nicht ausgelöst wird .

BTW - Flask Security documentation sagt:

Token basierende Authentifizierung durch Abfrage der Benutzerauthentifizierungstoken durch Ausführen eines HTTP POST mit den Authentifizierungsdaten als JSON-Daten gegen den Authentifizierungs-Endpunkt aktiviert ist.

Also versuchte ich POST, nicht GET (Still gleiches Problem der leeren request.json) Ich rief/login mit JSON-Daten als:

{"email": "[email protected]", "password": "test123"} 

und schickte eine Anfrage mit Postman Client in Google Chrome .

Doch request.json ist leer :(

Edit:. Ich konnte vorwärts bewegen mit Python Wunsch Modul-Details here

+0

Hallo Mandar, ich hoffe, du hast das gelöst, aber ich habe gerade eine Antwort geschrieben, die dir helfen kann: http://StackOverflow.com/a/27926284/992509 – SJoshi

+1

die Antwort, die du in deinem Blogpost auf die Startfrage gibst (wie man die csrf-Token bei der Verwendung von json-Login auf Flasch-Sicherheit) ist im Wesentlichen: Deaktivieren Sie die csrf-Authentifizierung in der Konfiguration von Flasch-Sicherheit. Ist das sicher zu tun? Gemäß diesem [Artikel] (https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/) ist es so lange wie Sie keine Cookies verwenden: " CSRF: Da Sie sich nicht auf Cookies verlassen, müssen Sie sich nicht vor Cross-Site-Anfragen schützen ... "Aber ist es wirklich genauso sicher wie die Verwendung von csrf-Token? – Sebastian

1

ich mit diesem Problem für Stunden letzte Nacht gekämpft.Hier ist, was für mich am Ende arbeiten:

Wenn ich meine App-Instanz erstellen:

app = Flask(__name__) 
app.config.from_object(config_by_name[config_name]) 

# Create database connection object 
app.db = db 
app.db.init_app(app) 

CsrfProtect(app) 

In meinem/login HTML:

<meta name="csrf-token" content="{{ csrf_token() }}"> 

Von Postman:

enter image description here

Hier war eine Alternative, die ich versucht habe, und vielleicht wird das erfolgreicher sein? Dies ist im Grunde die gleiche Antwort, dass die Kolben-Sicherheit Beispiel Apps geben:

enter image description here

2

Nun, es eine einfache Möglichkeit ist. Visit. Ein Konfigurationselement WTF_CSRF_ENABLED könnte auf False gesetzt werden, um das csrf zu deaktivieren. Dann geht alles wie du willst.

+1

Das hat mein Problem gelöst, danke. Es wurde wahrscheinlich downvoted, weil es eine Sicherheitsfunktion deaktiviert. Wenn der REST-Server jedoch nur Token-Authentifizierung und keine Cookie-basierte Authentifizierung durchführt, sind CSRF-Tokens redundant. (Ich begrüße alle Kommentare dazu!) – velotron

Verwandte Themen