Flask
Autorización y autenticación
Buscar..
Usando la extensión de inicio de sesión de matraz
Una de las formas más sencillas de implementar un sistema de autorización es usar la extensión de inicio de sesión de matraz . El sitio web del proyecto contiene un inicio rápido detallado y bien escrito, cuya versión más corta está disponible en este ejemplo.
Idea general
La extensión expone un conjunto de funciones utilizadas para:
- loguear usuarios en
- cerrar sesión de usuarios
- comprobar si un usuario ha iniciado sesión o no, y averiguar qué usuario es ese
Lo que no hace y lo que tiene que hacer por su cuenta:
- no proporciona una forma de almacenar los usuarios, por ejemplo, en la base de datos
- no proporciona una forma de verificar las credenciales del usuario, por ejemplo, nombre de usuario y contraseña
A continuación hay un conjunto mínimo de pasos necesarios para que todo funcione.
Recomendaría colocar todo el código relacionado con autenticación en un módulo o paquete separado, por ejemplo, auth.py
De esa manera puede crear las clases, los objetos o las funciones personalizadas necesarias por separado.
Crear un LoginManager
La extensión utiliza una clase LoginManager
que debe registrarse en el objeto de la aplicación Flask
.
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app) # app is a Flask object
Como se mencionó anteriormente, LoginManager
puede ser, por ejemplo, una variable global en un archivo o paquete separado. Luego se puede importar en el archivo en el que se crea el objeto Flask
o en la función de fábrica de su aplicación y se inicializa.
Especifique una devolución de llamada utilizada para cargar usuarios
Un usuario normalmente se cargará desde una base de datos. La devolución de llamada debe devolver un objeto que represente a un usuario correspondiente a la ID proporcionada. Debe devolver None
si el ID no es válido.
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id) # Fetch the user from the database
Esto se puede hacer directamente debajo de crear su LoginManager
.
Una clase representando a tu usuario.
Como se mencionó, la user_loader
llamada user_loader
tiene que devolver un objeto que represente a un usuario. ¿Qué significa eso exactamente? Ese objeto puede, por ejemplo, ser un envoltorio alrededor de objetos de usuario almacenados en su base de datos o simplemente directamente un modelo de su base de datos. Ese objeto tiene que implementar los siguientes métodos y propiedades. Eso significa que si la devolución de llamada devuelve el modelo de su base de datos, debe asegurarse de que las propiedades y los métodos mencionados se agreguen a su modelo.
is_authenticated
Esta propiedad debe devolver
True
si el usuario está autenticado, es decir, ha proporcionado credenciales válidas.user_loader
asegurarse de que los objetos que representan a sus usuarios devueltos por lauser_loader
llamadauser_loader
devuelvanTrue
para ese método.is_active
Esta propiedad debe devolver True si se trata de un usuario activo: además de autenticarse, también han activado su cuenta, no se han suspendido o cualquier condición que su aplicación tenga para rechazar una cuenta. Las cuentas inactivas pueden no iniciar sesión. Si no tiene un mecanismo presente, devuelva
True
con este método.is_anonymous
Esta propiedad debería devolver True si este es un usuario anónimo. Eso significa que su objeto de usuario devuelto por la
user_loader
llamadauser_loader
debe devolverTrue
.get_id()
Este método debe devolver un código Unicode que identifique de forma única a este usuario y se puede utilizar para cargar al usuario desde la
user_loader
llamadauser_loader
. Tenga en cuenta que este debe ser un Unicode: si el ID es de forma nativa un int o algún otro tipo, deberá convertirlo a Unicode. Si lauser_loader
llamadauser_loader
devuelve objetos de la base de datos, este método probablemente devolverá el ID de la base de datos de este usuario en particular. Por supuesto, la misma ID debería hacer que la devolución de llamadauser_loader
devuelva al mismo usuario más adelante.
Si desea hacer las cosas más fáciles para usted (** de hecho, se recomienda) puede heredar de UserMixin
en el objeto devuelto por la user_loader
llamada user_loader
(probablemente un modelo de base de datos). Puede ver cómo esos métodos y propiedades se implementan de forma predeterminada en esta mezcla aquí .
Entrar a los usuarios en
La extensión deja la validación del nombre de usuario y la contraseña ingresados por el usuario. De hecho, a la extensión no le importa si usa un combo de nombre de usuario y contraseña u otro mecanismo. Este es un ejemplo para iniciar sesión en los usuarios con el nombre de usuario y la contraseña.
@app.route('/login', methods=['GET', 'POST'])
def login():
# Here we use a class of some kind to represent and validate our
# client-side form data. For example, WTForms is a library that will
# handle this for us, and we use a custom LoginForm to validate.
form = LoginForm()
if form.validate_on_submit():
# Login and validate the user.
# user should be an instance of your `User` class
login_user(user)
flask.flash('Logged in successfully.')
next = flask.request.args.get('next')
# is_safe_url should check if the url is safe for redirects.
# See http://flask.pocoo.org/snippets/62/ for an example.
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)
En general, el registro de los usuarios se realiza llamando a login_user y pasando una instancia de un objeto que representa a su usuario mencionado anteriormente. Como se muestra, esto generalmente ocurrirá después de recuperar al usuario de la base de datos y validar sus credenciales, sin embargo, el objeto del usuario simplemente aparece mágicamente en este ejemplo.
He iniciado sesión en un usuario, ¿y ahora qué?
Se puede acceder al objeto devuelto por la user_loader
llamada user_loader
de varias maneras.
En plantillas:
La extensión lo inyecta automáticamente bajo el nombre
current_user
utilizando un procesador de contexto de plantilla. Para deshabilitar ese comportamiento y usar su conjunto de procesadores personalizadosadd_context_processor=False
en su constructorLoginManager
.{% if current_user.is_authenticated %} Hi {{ current_user.name }}! {% endif %}
En el código de Python:
La extensión proporciona un objeto vinculado a la solicitud llamado
current_user
.from flask_login import current_user @app.route("/hello") def hello(): # Assuming that there is a name property on your user object # returned by the callback if current_user.is_authenticated: return 'Hello %s!' % current_user.name else: return 'You are not logged in!'
Limitar el acceso rápidamente usando un decorador Un decorador
login_required
para iniciarlogin_required
puede usarse para limitar el acceso rápidamente.from flask_login import login_required @app.route("/settings") @login_required def settings(): pass
Desconectando usuarios
Los usuarios pueden logout_user()
sesión llamando a logout_user()
. Parece que es seguro hacerlo incluso si el usuario no ha iniciado sesión, por lo que @login_required
muy probable que el decorador @login_required
pueda ser omitido.
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(somewhere)
¿Qué sucede si un usuario no ha iniciado sesión y current_user
objeto current_user
?
Por defecto se devuelve un AnonymousUserMixin :
-
is_active
yis_authenticated
sonFalse
-
is_anonymous
esTrue
-
get_id()
devuelveNone
Para usar un objeto diferente para los usuarios anónimos, proporcione una llamada (ya sea una función de clase o de fábrica) que crea usuarios anónimos en su LoginManager
con:
login_manager.anonymous_user = MyAnonymousUser
¿Qué sigue?
Con esto concluye la introducción básica a la extensión. Para obtener más información sobre la configuración y las opciones adicionales, se recomienda encarecidamente leer la guía oficial .
Temporizar la sesión de inicio de sesión
Es una buena práctica cerrar la sesión de sesión después de un tiempo específico, puede lograrlo con Flask-Login.
from flask import Flask, session
from datetime import timedelta
from flask_login import LoginManager, login_require, login_user, logout_user
# Create Flask application
app = Flask(__name__)
# Define Flask-login configuration
login_mgr = LoginManager(app)
login_mgr.login_view = 'login'
login_mgr.refresh_view = 'relogin'
login_mgr.needs_refresh_message = (u"Session timedout, please re-login")
login_mgr.needs_refresh_message_category = "info"
@app.before_request
def before_request():
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=5)
La duración predeterminada de la sesión es de 31 días, el usuario debe especificar la vista de actualización de inicio de sesión en caso de que se agote el tiempo de espera.
app.permanent_session_lifetime = timedelta(minutes=5)
La línea anterior obligará al usuario a volver a iniciar sesión cada 5 minutos.