2014-12-08 11 views
8

Attualmente sto cercando un modo per proteggere un'API REST utilizzando l'autenticazione basata su token. Sto sviluppando l'API in Python usando Flask e ho scoperto l'estensione per la sicurezza dei flask che sembra avere molte caratteristiche interessanti.Autenticazione basata su token con estensione di sicurezza del pallone

Una delle funzionalità citate nella documentazione è l'autenticazione token.

Secondo la documentazione: autenticazione basata

token è attivato per il recupero dell'utente auth token eseguendo un POST HTTP con i dati di autenticazione come dati JSON contro l'endpoint autenticazione. Una chiamata riuscita a questo endpoint restituirà l'ID dell'utente e il relativo token di autenticazione . Questo token può essere utilizzato nelle richieste successive alle risorse protette .

Sono comunque ancora un po 'confuso su come implementare questa funzione utilizzando la sicurezza di flask. Alcune ricerche online mi hanno portato ad usare cose come @auth_token_required ma ho qualche problema a mettere tutto insieme. La documentazione sulla sicurezza dei flask di per sé non è molto utile.

Ad esempio, come può un utente ottenere un token di autenticazione? quali sono gli endpoint di autenticazione?

Sarebbe bello se tu potessi guidarmi nella giusta direzione. Esempi di codice sarebbe terribile troppo :-)

+3

Mi preoccupa che un'infrastruttura così critica non sia ben documentata. –

risposta

2

autenticazione endpoint è/login

guardare il codice di pallone-sicurezza here specificamente views.py: _render_json()

login() chiama _render_json che a attiva le chiamate get_auth_token() e restituisce il token di autenticazione.

Problema (per me) è farlo funzionare. Per me pare request.json vuota (da cui questo non non lavoro)

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

Speriamo che questo aiuta si sposta in avanti un po '.

6

Endpoint è/login, è inviare le credenziali come richiesta JSON corpo:

{'email':'[email protected]', 'password':'1234'} 

Tuttavia, per far funzionare tutto questo è necessario disabilitare i token CSRF nel pallone app (grazie Mandar Vaze):

app.config['WTF_CSRF_ENABLED'] = False 

Poi si fa ogni richiesta con il token nelle intestazioni HTTP:

Authentication-Token:WyI1NTE1MjhmNDMxY2Q3NTEwOTQxY2ZhYTgiLCI2Yjc4NTA4MzBlYzM0Y2NhZTdjZjIxNzlmZjhiNTA5ZSJd.B_bF8g.t1oUMxHr_fQfRUAF4aLpn2zjja0 

O come q uery stringa: esempio

http://localhost:5000/protected?auth_token=WyI1NTE1MjhmNDMxY2Q3NTEwOTQxY2ZhYTgiLCI2Yjc4NTA4MzBlYzM0Y2NhZTdjZjIxNzlmZjhiNTA5ZSJd.B_bF8g.t1oUMxHr_fQfRUAF4aLpn2zjja0 

client in Python 3:

import requests 
import json 

#do the login 
r = requests.post('http://localhost:5000/login', 
        data=json.dumps({'email':'[email protected]', 'password':'1234'}), 
        headers={'content-type': 'application/json'}) 
response = r.json() 
print(response) #check response 
token = response['response']['user']['authentication_token'] #set token value 

#Now you can do authorised calls 
r = requests.get('http://localhost:5000/protected', 
       headers={'Authentication-Token': token}) 
print(r.text) 

angolare frammento di esempio per ottenere il token:

$http.post('/login', {"email": $scope.formdata.login,"password":$scope.formdata.password}). 
      success(function(results) { 
      $window.sessionStorage.token = results.response.user.authentication_token; 
      }); 

angolare frammento di esempio per visitare le pagine protette:

if ($window.sessionStorage.getItem('token')) { 
       config.headers['Authentication-Token'] = $window.sessionStorage.getItem('token'); 
      } 
+0

Grazie. Usi l'autorizzazione basata su token di Flask-Security in produzione? –

+0

Attualmente solo in fase di sviluppo, non ho ancora una risposta definitiva a: abbiamo bisogno CSRF per migliorare la sicurezza in questo caso? Vedi anche: http://stackoverflow.com/questions/18436124/flask-security-csrf-token/27920113#comment46791688_27920113 – Sebastian

+0

La disabilitazione di CSRF non è accettabile a meno che non si disponga di viste html con i moduli. –

5

Ho trovato il token di Flask-Security non un buon candidato per il mio progetto. Raccomando invece di utilizzare token JWT.

I problemi con l'autenticazione basata su token di Flask-Security.

  1. necessario disabilitare CSRF a livello globale, questo non è buono quando si ha anche un'applicazione web tradizionale in cui CSRF token è desiderabile
  2. un modo semplice per rinnovare il token (senza inviare di nuovo la password)
  3. Can non controlla il payload del token, non ci sono API per inserire/ottenere dati dal token
  4. Quel token, in base alla progettazione, funziona solo con un'app Flask. Così, se il frontend applicazione ha bisogno di parlare con più RESTful API, questo lavoro ben abituato

Partenza JWT (pyjwt o flask-jwt) token, risolve tutti i problemi di cui sopra e di più.

+0

Se si utilizza wtforms non è necessario disabilitare CSRF a livello globale, è possibile utilizzare il decoratore '@ csrf_protect.exempt' nelle viste API. – bmjjr