Flask 实现登录状态持久化:让用户 1 天内无需重新登录

在开发 Web 应用时,用户登录状态的管理至关重要。默认情况下,Session 是临时的,一旦用户关闭浏览器,Session 通常会被清除,这意味着用户需要重新登录。然而,在许多应用场景中,我们希望实现持久化登录,即用户即使关闭了浏览器,在一段时间内仍然不需要重新登录。本文将介绍如何在 Flask 中实现这一功能,包括使用 Session 持久化、JWT Token 、以及Redis 存储 Session 的方法。


目录

  1. [使用 Flask-Session 持久化登录状态](#使用 Flask-Session 持久化登录状态)
  2. [使用 Cookies 存储 JWT Token 实现持久化登录](#使用 Cookies 存储 JWT Token 实现持久化登录)
  3. [Redis 持久化 Session,支持分布式架构](#Redis 持久化 Session,支持分布式架构)
  4. 总结

1. 使用 Flask-Session 持久化登录状态

Flask 使用 Session 管理用户的登录状态。默认情况下,Session 是临时的,通常在用户关闭浏览器后失效。为了让用户的登录状态可以持续一段时间(如 1 天),我们可以将 Session 配置为"永久",并设置一个有效期。

代码实现
python 复制代码
from flask import Flask, session, redirect, url_for, request
import datetime

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# 设置 Session 的过期时间为1天
app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=1)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # 假设用户名和密码正确
        if username == 'test_user' and password == 'test_password':
            session.permanent = True  # 使 session 永久化
            session['username'] = username  # 存储用户信息在 session 中
            return redirect(url_for('dashboard'))
        return 'Invalid credentials'
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=password name=password>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/dashboard')
def dashboard():
    if 'username' in session:
        return f'Hello, {session["username"]}! You are logged in.'
    return redirect(url_for('login'))

@app.route('/logout')
def logout():
    session.pop('username', None)  # 删除 session 中的用户信息
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)
解释
  • Session 持久化 :通过 session.permanent = True 将 Session 设置为永久,即使关闭浏览器,Session 仍然会保持。
  • PERMANENT_SESSION_LIFETIME:设置为 1 天,使得用户在登录后的 1 天内保持登录状态。

2. 使用 Cookies 存储 JWT Token 实现持久化登录

另一种实现持久化登录的方式是通过 JWT (JSON Web Token),将生成的 Token 存储在 Cookies 中,并设置过期时间。在用户访问受保护的路由时,服务器可以通过解码 Token 验证用户身份,从而实现 1 天内无需重新登录。

代码实现
python 复制代码
from flask import Flask, request, redirect, url_for, render_template, make_response
import datetime
import jwt

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# JWT 秘钥
JWT_SECRET = 'your_jwt_secret'

def create_jwt_token(username):
    payload = {
        'username': username,
        'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1)  # 1天后过期
    }
    token = jwt.encode(payload, JWT_SECRET, algorithm='HS256')
    return token

def verify_jwt_token(token):
    try:
        decoded = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])
        return decoded['username']
    except (jwt.ExpiredSignatureError, jwt.InvalidTokenError):
        return None

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if username == 'test_user' and password == 'test_password':
            token = create_jwt_token(username)
            resp = make_response(redirect(url_for('dashboard')))
            # 设置 Cookie,保存1天
            resp.set_cookie('auth_token', token, max_age=60*60*24)  # 1天有效期
            return resp
        return 'Invalid username or password', 401
    return render_template('login.html')

@app.route('/dashboard')
def dashboard():
    token = request.cookies.get('auth_token')
    if token:
        username = verify_jwt_token(token)
        if username:
            return f'Hello, {username}! You are logged in.'
    return redirect(url_for('login'))

@app.route('/logout')
def logout():
    resp = make_response(redirect(url_for('login')))
    resp.delete_cookie('auth_token')  # 删除 Cookie
    return resp

if __name__ == '__main__':
    app.run(debug=True)
解释
  • JWT:登录成功后生成 JWT Token,将其存储在 Cookie 中,并设置有效期为 1 天。
  • Token 验证:在用户访问受保护的路由时,通过解码 Token 来验证用户身份。

3. Redis 持久化 Session,支持分布式架构

在更复杂的应用场景中,可能需要跨多个服务器或进程保持用户的登录状态。这时,可以使用 Redis 或其他数据库来持久化 Session。Redis 允许将 Session 存储在服务器端,并支持集群化和分布式应用场景。

代码实现
python 复制代码
from flask import Flask, session
from flask_session import Session
import redis

app = Flask(__name__)

# 配置 Redis 作为 Session 后端
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_PERMANENT'] = True
app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=1)
app.config['SESSION_USE_SIGNER'] = True
app.config['SESSION_KEY_PREFIX'] = 'myapp_'
app.config['SESSION_REDIS'] = redis.StrictRedis(host='localhost', port=6379, db=0)

# 初始化 Session
Session(app)

@app.route('/login')
def login():
    session['username'] = 'test_user'  # 存储用户名到 Session
    return 'Logged in successfully!'

@app.route('/dashboard')
def dashboard():
    username = session.get('username')
    if username:
        return f'Hello, {username}!'
    return 'You need to log in first.', 401

if __name__ == '__main__':
    app.run(debug=True)
解释
  • Redis 后端:Session 数据保存在 Redis 中,支持多服务器之间的 Session 同步和持久化。

4. 总结

通过本文,我们介绍了如何在 Flask 应用中实现持久化登录。无论是使用 Session 还是 JWT Token ,都可以让用户在 1 天内无需重新登录。如果您的应用需要分布式架构支持,Redis 是一个很好的选择,用于持久化存储 Session 数据。根据应用的需求,您可以选择适合的方案来优化用户体验。


相关推荐
tangwangbi6 分钟前
Linux 系统配置文件:/etc/profile、~/.bashrc 和 ~/.bash_profile 三者之间的区别与作用
linux·运维·bash
天远数科11 分钟前
风险治理实战:基于天远车信盟出险构建自动化理赔核保流水线
java·网络·人工智能·自动化
蜀道山老天师29 分钟前
Shell Bash变量与运算符(含条件测试与流程控制)
linux·运维·bash
别走!万哥爱你30 分钟前
Python 中可以用于在已排序的列表中查找特定元素的位置的是什么?
python
Mr.朱鹏37 分钟前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
mengge.cloud1 小时前
存储技术基础小白教程
linux·运维·服务器·wpf·存储
志栋智能1 小时前
安全超自动化如何支持大规模安全运营?
网络·安全·自动化
星恒讯工业路由器1 小时前
农村宽带覆盖难?无线专网方案正在改写“最后一公里”规则
网络·物联网·网桥·无线网桥·农村宽带覆盖·无线专网·户外网络
wxwx_bscxy3222 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
tang777892 小时前
反爬虫场景下代理IP池的动态扩容与失效IP自动清理方案实现
linux·服务器·网络·爬虫代理·住宅代理ip