8

J'essaie de permettre aux utilisateurs de se connecter à mon application Flask en utilisant leurs comptes depuis un service Web distinct. Je peux contacter l'API de ce service web et recevoir un jeton de sécurité. Comment puis-je utiliser ce jeton pour authentifier les utilisateurs afin qu'ils aient accès aux vues restreintes?Comment implémentez-vous l'authentification par jeton dans Flask?

Je n'ai pas besoin de sauvegarder les utilisateurs dans ma propre base de données. Je veux seulement les authentifier pour une session. Je crois que cela peut être fait en utilisant Flask-Security et le décorateur @auth_token_required mais la documentation n'est pas très détaillée et je ne suis pas sûr de savoir comment l'implémenter.

EDIT:

Voici un exemple de code:

@main.route("/login", methods=["GET", "POST"]) 
def login(): 

    payload = {"User": "john", "Password": "password123"} 
    url = "http://webserviceexample/api/login" 
    headers = {'content-type': 'application/json'}) 

    #login to web service 
    r = requests.post(url, headers=headers, json=payload) 
    response = r.json() 

    if (r.status_code is 200): 
     token = response['user']['authentication_token'] 

     # allow user into protected view 

    return render_template("login.html", form=form) 


@main.route('/protected') 
@auth_token_required 
def protected(): 
    return render_template('protected.html') 
+0

Vous devez stocker les utilisateurs avec le jeton; et confirmez la validité du jeton par rapport au service. Sinon, vous devrez authentifier les visiteurs chaque fois contre le service de tiers à chaque fois qu'ils commencent. –

+0

À chaque fois, voulez-vous dire pour chaque session? Si c'est le cas, c'est bien qu'ils devraient s'authentifier à nouveau. Y a-t-il une raison pour que ce soit un problème? – Amerikaner

Répondre

11

Salut Amedrikaner!

Il semble que votre cas d'utilisation soit assez simple pour que nous puissions le faire nous-mêmes. Dans le code ci-dessous, je stocke votre jeton dans la session des utilisateurs et j'enregistre un nouveau wrapper. Commençons par créer notre propre wrapper, je les mets simplement dans un fichier wrappers.py mais pouvez-vous le placer où vous voulez.

def require_api_token(func): 
    @wraps(func) 
    def check_token(*args, **kwargs): 
     # Check to see if it's in their session 
     if 'api_session_token' not in session: 
      # If it isn't return our access denied message (you can also return a redirect or render_template) 
      return Response("Access denied") 

     # Otherwise just send them where they wanted to go 
     return func(*args, **kwargs) 

    return check_token 

Cool!

Maintenant que nous avons implémenté notre wrapper, nous pouvons simplement enregistrer leur jeton dans la session. Super simple. Modifions votre fonction ...

@main.route("/login", methods=["GET", "POST"]) 
def login(): 

    payload = {"User": "john", "Password": "password123"} 
    url = "http://webserviceexample/api/login" 
    headers = {'content-type': 'application/json'}) 

    #login to web service 
    r = requests.post(url, headers=headers, json=payload) 
    response = r.json() 

    if (r.status_code is 200): 
     token = response['user']['authentication_token'] 

     # Move the import to the top of your file! 
     from flask import session 

     # Put it in the session 
     session['api_session_token'] = token 

     # allow user into protected view 

    return render_template("login.html", form=form) 

Maintenant, vous pouvez vérifier les vues protégées en utilisant l'emballage @require_api_token, comme ça ...

@main.route('/super_secret') 
@require_api_token 
def super_secret(): 
    return "Sssshhh, this is a secret" 

EDIT Woah! J'ai oublié de mentionner que vous devez définir votre SECRET_KEY dans la configuration de vos applications. Un simple fichier config.py avec SECRET_KEY = "SOME_RANDOM_STRING" fera l'affaire. Puis chargez-le avec ...

main.config.from_object(config) 
+0

C'est exactement ce que je cherchais. Merci F Boucaut! – Amerikaner

+0

Avons-nous juste besoin de ces deux éléments ou ne devrait-il pas y avoir une autre fonction pour vérifier les informations d'identification de l'utilisateur par rapport à la base de données? –

+0

@EvanBurbidge Désolé pour la réponse tardive. Cette implémentation était spécifiquement destinée à authentifier les utilisateurs par rapport à une API externe ailleurs. Tout comme vous voulez suivre un flux de connexion utilisateur standard, consultez ce lien pour plus d'informations https://flask-login.readthedocs.io/en/latest/ –