flask-login I have implemented the login function using flask-login, but I wanted to know the internal mechanism, so I investigated the mechanism from the documentation and source code!
You may extend the UserMixin class.
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
@login_manager.user_loader
def load_user(userid):
return User(userid)
The argument received by load_user here is the value returned by get_id () defined in the User class. If necessary, let get_id () return the value needed to get the user from the DB: smile:
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)
Pass user to login_user and flask-login will do the rest. It mainly stores the information necessary to maintain the login status in the session, updates the user in the request context, sends a login signal, etc .: bow:
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(somewhere)
It's very simple, just call logout_user. In the logout_user function, the logged-in user is fetched and the logout process is executed, so there is no need to pass the user. Roughly speaking, it's the opposite of logging in. To keep the login status, delete the value held in the session, update the user in the request context to anonymous_user, and send the logout signal. : rolling_eyes:
In the login_required decorator, get the current_user. current_user attempts to get the user from the information stored in the session (specifically user_id). [a] Since it is before login, the session does not have user_id, so getting the user fails. If request_loader is defined, use them to try to log in. Since request_loader is not defined this time, current_user will be Anonymous User. Since is_authenticated defined in the Anonymous User class returns False, it is determined that it is not authenticated, and LoginManger's unauthorized () is called to redirect to the login screen.
It is the same as [a] of the behavior before login. If the user is successfully acquired, the user is returned as it is. Check if the user is authenticated with is_authenticated. Since it is not an Anonymous User, True is returned as defined in the User model. It is determined to be authenticated, so subsequent processing continues: laughing:
--HttpOnly attribute By default, Flask holds session information on the client side, called a cookie based session. Therefore, set SESSION_COOKIE_HTTPONLY to True to prevent javascript from accessing this information. (Default is True) [1]
--Limited cookie based session cookie transmission to Https only Let's set SESSION_COOKIE_SECURE to True. (Default is False) [2]
--Session protection Flask-login generates a hash value from the IP address and user-agent and holds it in the session, so if that value changes from the previous time, the default basic mode behavior will drop the login state. However, on the flask side, if the session persistence setting is set, the login state will be maintained, but this session will be flagged as not fresh. In strong mode, the login state is discarded if the hash has changed.
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