Flask-Login practice: user login, logout and session management
📂 Stage: Stage 3 - User System (Security) 🔗 Related chapters: 密码安全加密 · 数据验证
1. Why choose Flask-Login?
Manually managing user sessions sounds easy, but when you actually implement it, you will encounter a series of pitfalls: cookie hijacking protection, automatic redirection without logging in, persistence of the "remember me" function, acquisition of the current user across requests... If you write these logics from scratch, you will reinvent the wheel at best, and bury security risks at worst.
Flask-Login has encapsulated all these common logics. You only need to complete two things:
- Implement User loading callback - tell Flask-Login how to find the user object based on ID;
- Provides login/logout routing - call the
login_user()andlogout_user()That’s it.
The rest of the session management,current_useracting,@login_requiredProtect, remember me cookies, and more, Flask-Login has it all.
Core Competencies at a Glance
- ✅Creation, destruction and automatic maintenance of user Session
- ✅ Globally available
current_user, the current user can be directly obtained in the view and template - ✅
@login_requiredDecorator, one line of code to protect routing - ✅ Automatic cookie management for the "Remember Me" function (configurable validity period)
- ✅ Unified redirection and message prompts when you are not logged in or have no permissions
- ✅ Built-in implementation of anonymous users, no need to write anonymous objects yourself
Install
2. Global initialization and basic configuration
Flask recommends using the Application Factory Pattern to create application instances, which makes it more convenient to manage configurations in multiple environments (development, testing, production). For this reason, we need to separate the initialization of third-party extensions to avoid circular imports.
2.1 Create extension manager
Create a new oneapp/extensions.pyFile, specifically used to store instantiations of extensions such as Flask-Login:
Here will belogin_viewpoint toauthblueprintloginRouting so that when a user is not logged in and accesses a protected page, they are automatically redirected to the login page.login_messageIt will be stored in the flash message for template rendering.
2.2 Bind the extension in the application factory
Next, bind the extension in the application factory function and implement the core user loading callback:
Tip:
SECRET_KEYBe sure to read it from the environment variables during deployment and ensure it is random and confidential. It must not be hard-coded in the code and submitted to the repository.
3. User model: inheritanceUserMixin
Flask-Login requires user objects to implement four core properties/methods:
is_authenticated– Are you logged in?is_active– Whether the account is activated (can be disabled)is_anonymous– Whether it is an anonymous userget_id()– Returns the user’s unique identifier (string or number)
In order to prevent yourself from implementing these methods one by one, directly inheritUserMixinThat’s it. If there is a business need, you can also override one of the attributes (such asis_active)。
In this way, the user model meets all the requirements of Flask-Login and has database mapping capabilities.
4. Core routing: login and logout
4.1 Login routing
The login route is responsible for handling form submission, password verification and session creation. The following uses the Flask-WTF form as an example. You can also use it directlyrequest.formGet data.
A few key points:
check_password_hashUsed to compare the password entered by the user with the hash value stored in the database to achieve secure password verification.login_user(user, remember=False)Create a login session; whenremember=TrueWhen , a long-term "remember me" cookie will be written, whose validity period is the previously configuredREMEMBER_COOKIE_DURATION。- Prevent open redirect: only accept
/The relative path at the beginning is used as a jump target to prevent attackers from using query parameters to redirect users to malicious websites.
4.2 Logout routing
Logout logic is very simple, one linelogout_user()This will clear the user session and "remember me" cookies.
5. Route protection—from basics to advanced
5.1 Basic usage:@login_required
Just add above the route@login_requiredDecorator to force login. When users who are not logged in access, they will be automatically redirected tologin_viewspecified address.
Pay attention to the order of decorators: Flask's routing decorators are executed from bottom to top, so usually
@login_requiredput on@app.routeabove (that is, the layer immediately next to the function definition).
5.2 Partial protection: decide whether to require login according to the request method
Some scenarios require more fine-grained control, such as "viewing comments is public, and you must log in to write comments." At this time, you can not use the decorator directly, but passcurrent_user.is_authenticatedDetermine inside the view.
5.3 Custom permission decorator
Login is only the first threshold. In many cases, it is also necessary to verify whether the user has specific permissions, such as administrator access to the backend. We can write our own permission decorator:
When using, place the custom decorator in@login_requiredAfter that (make sure to verify login first, then permissions):
6. Universal variables in templates:current_user
current_userNot only can it be used in view functions, but it is also globally available in Jinja2 templates. It couldn't be more convenient to use it to control the display of navigation bar and buttons.
7. Safety practices cannot be ignored
Even though Flask-Login helps us encapsulate many details, there are still several security points that we need to check ourselves:
-
SECRET_KEYIt must be strongly random and confidential used in production environmentsecrets.token_hex(32)Generate, inject via environment variables, never hardcode or commit to code repository. -
Prevent open redirect vulnerability Jump parameters after login
nextWhitelist verification is required, and only the/Starting with a relative path, external URLs are rejected. -
Force HTTPS and set secure cookie flag After deploying to production, be sure to set
SESSION_COOKIE_SECURE=True, ensuring that session cookies are only transmitted in HTTPS connections to prevent man-in-the-middle attacks. -
Passwords should never be stored in clear text Must be used when registering
werkzeug.security.generate_password_hash()Encrypt password and reuse it when logging incheck_password_hash()Compare. -
Decorator order matters The custom permission decorator should be placed in
@login_requiredbelow (near the layer where the function is defined), make sure to verify the login status first, and then verify the specific permissions.
8. Quick summary
Finally, a list of commonly used Flask-Login operations is compiled for you for quick reference:
🔗 Extended reading

