2013-08-26 24 views
10

Mam aplikację kolby, która służy jako backend API REST. Chciałbym zaimplementować uwierzytelnianie oparte na tokenach dla zaplecza, ale aby to zrobić, muszę pobrać token użytkownika. Dokumentacja Flask-Security wyraźnie mówi, że aby pobrać token, należy wykonać test POST HTTP z danymi uwierzytelniającymi jako danymi JSON do punktu końcowego uwierzytelniania. Niestety nie rozumiem, jak odzyskać token CSRF potrzebny do wykonania takiego żądania.Flask-Security CSRF token

Jeśli użyję strony logowania/szablonu dostarczonego z rozszerzeniem, token CSRF zostanie przekazany klientowi w ukrytym polu w formularzu. Pytanie brzmi:

Jak pobrać token CSRF bez uzyskiwania dostępu i analizowania strony logowania, na przykład z aplikacji angularowej JS przy użyciu metod $ http lub aplikacji mobilnej?

Oczywiście mogłem uniknąć używania Flask-Security i samemu wdrożyć te elementy, ale jestem stosunkowo niedoświadczony przez webappy i czuję, że mogę podejść do tego w niewłaściwy sposób.

+0

Jak to zrobiłeś w końcu? – kyrre

+0

Skończyłem sam wdrażając warstwę bezpieczeństwa. Przepraszam, nie mam dla ciebie lepszej odpowiedzi. – Jacopo

+0

Należy pamiętać, że nie ma bezpiecznego sposobu przechowywania tokenów w angularjs, patrz np. [tutaj] (https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/). Bezpieczną opcją jest umożliwienie serwerowi przechowywania tokena w pliku cookie opartym tylko na protokole http + włączanie ochrony CSRF. Jeśli wszystko, co musisz porozmawiać, to angularjs, możesz równie dobrze skorzystać z sesji (+ anty-CSRF). – Adversus

Odpowiedz

2

Nie przetestowałem, że to działa, ale z krótkiej kontroli source code wydaje się, że musisz wysłać żądanie GET do adresu URL logowania z typem treści ustawionym na application/json. Flask-Security odpowiada na to żądanie za pomocą formularza logowania JSON zawierającego token. Gdy masz token, możesz wysłać żądanie POST.

+0

Dzięki, że położyłeś właściwą drogę. Oprócz wykonania żądania GET, muszę przekazać pewne dane json z prośbą, w przeciwnym razie "request.json" jest puste w Flask, a metoda "_render_json" nie jest wywoływana. Niestety jednak powoduje to błąd w linii 45 źródła, które podłączyłeś, ponieważ formularz nie ma atrybutu użytkownika. Ale krótko patrząc na kod, myślę, że atrybut użytkownika powinien zostać ustawiony podczas sprawdzania poprawności, ale nie ma to miejsca w przypadku tego żądania. Będę musiał dalej kopać. Jeszcze raz dziękuję – Jacopo

+0

OK Ustaliłem błąd. Metoda "validate_on_submit" w Flask-WTF sprawdza najpierw dla "is_submitted", która jest fałszywa dla żądania GET. Zapobiega to wywołaniu metody "sprawdzania poprawności" i przypisaniu atrybutu "użytkownika" w formularzu. Jednak wywołanie metody "sprawdzania poprawności" powoduje ręczne wygenerowanie błędu "brak tokena CSRF", a my wróciliśmy na początku. – Jacopo

4

miałem podobny przypadek użycia, a zakończył go rozwiązać, wykonując ten przykład z docs Kolba-WTF: https://flask-wtf.readthedocs.org/en/latest/csrf.html#ajax

Więc przez CSRF Ochrona aplikację poprzez CsrfProtect(app) The csrf_token() będzie dostępny we wszystkich szablonów. Następnie można łatwo udostępnić go za pomocą tagu skryptu:

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

Teraz dodać token do danych pocztowych do kolby-zabezpieczający końcowym/logowania.

+2

Dziękuję za odpowiedź, ale w końcu wdrożyłem własne rozwiązanie do zarządzania użytkownikami. Działa to również wtedy, gdy podajesz strony za pomocą aplikacji Flask i renderujesz szablon za pomocą Jinja. W przypadku, gdy używasz aplikacji Flask tylko dla zaplecza (REST API), a frontend jest obsługiwany innymi metodami, musisz podać punkt końcowy API, aby pobrać token i wyrenderować go w odpowiedzi json. Nie jestem pewien, jak to zadziała, może spróbuję. – Jacopo

0

[Pisanie jako odpowiedź, ponieważ nie ma wystarczającej reputacji komentarz]

mam napotkasz dokładnie ten sam problem jak Jacopo, że - request.json jest pusta, a zatem get_auth_token() nie jest wyzwalany .

BTW - Flask Security documentation mówi: uwierzytelnianie oparte

Reklamowe jest włączone pobieranie tokenu uwierzytelniania użytkownika poprzez wykonanie HTTP POST ze szczegółami uwierzytelniania jak dane JSON przeciwko końcowego uwierzytelniania.

Więc próbowałem POST, nie GET (nadal ten sam problem z pustym request.json) Zadzwoniłem/login z danych JSON jak:

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

i wysłał żądanie przy użyciu Postman klienta w Google Chrome .

Jednak request.json jest pusty :(

Edit. Byłem w stanie poruszać się do przodu za pomocą modułu żądania Python Dane here

+0

Witam Mandar, mam nadzieję, że to rozwiązałeś, ale właśnie napisałem odpowiedź, która może pomóc: http://stackoverflow.com/a/27926284/992509 – SJoshi

+1

odpowiedź, którą dajesz w swoim blogu na pytanie o rozpoczęcie (jak wdrożyć csrf token w przypadku korzystania z loginu json na flask-security) jest w istocie: wyłącza uwierzytelnianie csrf w konfiguracji ochrony skrzynki. Czy to jest do zrobienia? Zgodnie z tym [artykułem] (https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/) jest tak długo, jak nie używasz plików cookie: " CSRF: skoro nie polegasz na plikach cookie, nie musisz chronić się przed żądaniami między witrynami ... "Ale czy to naprawdę tak samo, jak używanie tokenów csrf? – Sebastian

1

Walczyłem z tym problemem przez kilka godzin w nocy.Oto, co skończyło się pracować dla mnie:

Kiedy tworzę aplikację instancję:

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) 

W moim/logowania HTML:

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

Od Listonosz:

enter image description here

Oto alternatywa, którą próbowałem, a może to będzie bardziej udane? Jest to w zasadzie ta sama odpowiedź, że kolba przykładowe aplikacje dają bezpieczeństwo:

enter image description here

2

Cóż, nie jest to prosty sposób. Visit. Element konfiguracji WTF_CSRF_ENABLED można ustawić na False, aby wyłączyć csrf. Wtedy wszystko idzie tak, jak chcesz.

+1

To rozwiązało mój problem, dzięki. Prawdopodobnie została cofnięta, ponieważ wyłącza funkcję bezpieczeństwa. Ale jeśli serwer REST wykonuje tylko uwierzytelnianie tokenowe, a nie uwierzytelnianie oparte na plikach cookie, tokeny CSRF są nadmiarowe. (Z zadowoleniem przyjmuję wszystkie komentarze na ten temat!) – velotron

Powiązane problemy