[PYTHON] J'ai étudié le mécanisme de connexion flask!

flask-login J'ai implémenté une fonction de connexion en utilisant flask-login, mais je voulais connaître le mécanisme interne, alors j'ai étudié le mécanisme à partir de la documentation et du code source!

Définissons les propriétés / méthodes suivantes dans la classe: dolphin: User

Vous pouvez étendre la classe UserMixin.

: dolphin: Initialisons flask_login

from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"

Définissons une fonction de rappel à charger: dolphin: user

@login_manager.user_loader
def load_user(userid):
    return User(userid)

L'argument reçu par load_user ici est la valeur renvoyée par get_id () définie dans la classe User. Si nécessaire, laissez get_id () retourner la valeur nécessaire pour extraire l'utilisateur de la base de données: smile:

: cat: Implémentons le processus de connexion

def login():
    form = LoginForm()
    if form.validate_on_submit():
        login_user(user)
        flask.flash('Logged in successfully.')
        next = flask.request.args.get('next')
        if not is_safe_url(next):
            return flask.abort(400)
        return flask.redirect(next or flask.url_for('index'))
    return flask.render_template('login.html', form=form)

Passez l'utilisateur à login_user et flask-login fera le reste. Il stocke principalement les informations nécessaires pour maintenir l'état de connexion dans la session, met à jour l'utilisateur du contexte de la requête, envoie un signal de connexion, etc.: arc:

: dog: Implémentons le traitement de déconnexion

@app.route("/logout")
@login_required
def logout():
    logout_user()
    return redirect(somewhere)

C'est très simple, il suffit d'appeler logout_user. Dans la fonction logout_user, l'utilisateur connecté est récupéré et le processus de déconnexion est exécuté, il n'est donc pas nécessaire de passer l'utilisateur. En gros, c'est l'opposé de la connexion. Pour conserver l'état de connexion, supprimez la valeur conservée dans la session, mettez à jour l'utilisateur dans le contexte de la demande en anonymous_user et envoyez le signal de déconnexion. : Rolling_eyes:

: lapin: Comportement avant la connexion

Dans le décorateur login_required, récupérez le current_user. current_user tente d'obtenir l'utilisateur à partir des informations stockées dans la session (en particulier user_id). [une] Puisqu'il est avant la connexion, la session n'a pas user_id, donc l'obtention de l'utilisateur échoue. Si request_loader est défini, utilisez-les pour essayer de vous connecter. Puisque request_loader n'est pas défini cette fois, current_user sera un utilisateur anonyme. Puisque is_authenticated, qui est défini dans la classe Utilisateur anonyme, retourne False, il est déterminé qu'il n'est pas authentifié, et LoginManger's unauthorized () est appelé pour rediriger vers l'écran de connexion.

: lapin: Comportement après connexion

C'est la même chose que [a] du comportement avant la connexion. Si l'utilisateur est acquis avec succès, l'utilisateur est renvoyé tel quel. Vérifiez si l'utilisateur est authentifié avec is_authenticated. Puisqu'il ne s'agit pas d'un utilisateur anonyme, il renvoie True comme défini dans le modèle User. Puisqu'il est déterminé à être authentifié, le traitement suivant se poursuivra: rire:

: ours: Mesures de sécurité

Attribut --HttpOnly Par défaut, Flask contient les informations de session côté client, appelées session basée sur les cookies. Par conséquent, définissez SESSION_COOKIE_HTTPONLY sur True pour empêcher JavaScript d'accéder à ces informations. (La valeur par défaut est True) [1]

By default, it is activated in "basic" mode. It can be disabled in the app’s configuration by setting the SESSION_PROTECTION setting to None, "basic", or "strong". When session protection is active, each request, it generates an identifier for the user’s computer (basically, a secure hash of the IP address and user agent). If the session does not have an associated identifier, the one generated will be stored. If it has an identifier, and it matches the one generated, then the request is OK. If the identifiers do not match in basic mode, or when the session is permanent, then the session will simply be marked as non-fresh, and anything requiring a fresh login will force the user to re-authenticate. (Of course, you must be already using fresh logins where appropriate for this to have an effect.) If the identifiers do not match in strong mode for a non-permanent session, then the entire session (as well as the remember token if it exists) is deleted. [3]

[1] https://flask.palletsprojects.com/en/1.1.x/config/#SESSION_COOKIE_HTTPONLY [2] https://flask.palletsprojects.com/en/1.1.x/config/#SESSION_COOKIE_SECURE [2] https://flask-login.readthedocs.io/en/latest/#session-protection

Recommended Posts

J'ai étudié le mécanisme de connexion flask!
J'ai étudié l'algorithme d'apprentissage de renforcement du trading d'algorithmes
J'ai étudié à quoi ressemble la lunette
J'ai étudié la superposition de l'arborescence des appareils
J'ai étudié la méthode X-means qui estime automatiquement le nombre de clusters
J'ai étudié le comportement de la différence entre lien dur et lien symbolique
Expliquer le mécanisme de la classe de données PEP557
J'ai vérifié le contenu du volume du docker
J'ai essayé le serveur asynchrone de Django 3.0
J'ai vérifié les options de copyMakeBorder d'OpenCV
La structure des dossiers de Flask est résumée
Je ne connaissais pas les bases de Python
Le modèle de projet Python auquel je pense.
Examinons le mécanisme de la chinchirorine de Kaiji
J'ai essayé la fonction de tableau croisé dynamique des pandas
J'ai lu l'implémentation de range (Objects / rangeobject.c)
J'ai vérifié la liste des touches de raccourci de Jupyter
J'ai essayé de corriger la forme trapézoïdale de l'image
Essayez Progate Free Edition [Python I]
J'ai vérifié la période de rétention de session de django
J'ai vérifié la vitesse de traitement de la numpy unidimensionnelle
J'ai touché certaines des nouvelles fonctionnalités de Python 3.8 ①
J'ai lu et implémenté les variantes de UKR
Je souhaite personnaliser l'apparence de zabbix
J'ai essayé d'utiliser le filtre d'image d'OpenCV
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
Le début de cif2cell
[Recette du formateur] J'ai touché le flacon du framework Python.
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé le tutoriel MNIST de tensorflow pour les débutants.
Le sens de soi
J'ai suivi la mise en place de la commande du (première moitié)
J'ai comparé l'identité des images par moment Hu
[Statistiques] Comprendre le mécanisme des graphiques Q-Q avec animation.
Peut-être ai-je surestimé l'impact de Shell Shock sur CGI
le zen de Python
L'histoire de sys.path.append ()
J'ai vérifié les spécifications de sortie du LSTM bidirectionnel de PyTorch
J'ai vérifié les versions de Blender et Python
Je veux bien comprendre les bases de Bokeh
Les performances de PHP étaient meilleures que ce à quoi je m'attendais
J'ai examiné l'argument class_weight de la fonction softmax_cross_entropy de Chainer.
J'ai mesuré les performances d'un million de documents avec mongoDB
J'ai vérifié le système d'exploitation et le shell par défaut de docker-machine
J'ai suivi la mise en place de la commande du (seconde moitié)
J'ai essayé d'utiliser l'API de Sakenowa Data Project
J'ai essayé de visualiser les informations spacha de VTuber
[Ev3dev] Comprenons le mécanisme de contrôle LCD (écran)
J'ai étudié le temps de calcul de "X dans la liste" (recherche linéaire / recherche dichotomique) et "X dans l'ensemble"
J'ai essayé d'effacer la partie négative de Meros
J'ai essayé de gratter la publicité du site de dessin animé piraté
J'ai compté les grains
J'ai essayé la méthode la plus simple de classification de documents multi-étiquettes
La vengeance des types: la vengeance des types
J'ai essayé de classer les voix des acteurs de la voix
Je souhaite augmenter la sécurité de la connexion SSH
J'ai recherché le contenu de l'agent CloudWatch Logs