Flask-Session问题:同一浏览器下不同用户购物车数据串扰排查
问题描述
我开发了一个包含用户登录和购物车功能的小型Flask应用,使用Flask-Session扩展和SQLite3。遇到的问题如下:在同一浏览器中,以用户A登录并向购物车添加商品,退出后登录用户B(未关闭浏览器),此时查看B的购物车,仍能看到用户A添加的商品,但预期应为空购物车。
错误原因
问题出在会话清理不彻底和购物车初始化逻辑漏洞:
- 退出登录时仅移除了
userName会话变量,但cart变量仍保留在会话中,导致新用户登录时直接复用旧购物车数据。 - 登录逻辑中仅在
cart不存在时才初始化空列表,但如果会话中已有旧的cart数据,就不会重新初始化,直接继承了上一个用户的购物车内容。
修复方案
- 退出登录时,同步清理会话中的购物车数据,或直接清空整个会话。
- 登录成功后,强制初始化当前用户的空购物车,覆盖可能存在的旧数据。
修改后的完整代码
from flask import Flask, render_template, redirect, url_for, request, session from flask_session import Session import sqlite3 app = Flask(__name__) app.config['SECRET_KEY'] = "ASecretKey-1" app.config['SESSION_PERMANENT'] = True app.config['SESSION_TYPE'] = 'filesystem' Session(app) def connectDB(): dbObj = sqlite3.connect('shoppingCart.db') dbObj.row_factory = sqlite3.Row cur = dbObj.cursor() return (dbObj, cur) def disConnectDB(dbObj, cur): cur.close() dbObj.close() del cur, dbObj @app.route('/') @app.route('/home') def home(): if not session.get('userName'): return render_template('login.html', pageTitle='Login Page') dbObj, cur = connectDB() data = cur.execute('SELECT rowid, * FROM inventory').fetchall() disConnectDB(dbObj, cur) contextValues=dict(pageTitle='HomePage', data=data, userName=session.get('userName')) return render_template('home.html', **contextValues) @app.get('/login') @app.post('/login') def login(): userName = request.form.get('userName') password = request.form.get('password') if (not userName) or (not password): return "<h1 style='color:darkorange'>Form incomplete.</h1>" else: dbObj, cur = connectDB() data = cur.execute("SELECT * FROM users WHERE userName =? AND password=?", (userName,password,)).fetchone() disConnectDB(dbObj, cur) print("*"*25,data) if data: session['userName'] = userName # 强制初始化当前用户的空购物车,覆盖旧数据 session['cart'] = [] else: return "<h1 style='color:darkorange'>Incorrect Credentials.</h1>" return redirect(url_for('home')) @app.route('/logout') def logout(): # 移除用户名和购物车会话数据 session.pop('userName', None) session.pop('cart', None) # 也可以使用 session.clear() 彻底清空所有会话内容 return redirect(url_for('home')) @app.route('/cart') def cart(): # 兜底处理,确保cart始终为列表类型 cart = session.get('cart', []) return render_template('cart.html',pageTitle='cart',cart=cart) @app.route('/addtocart', methods=['GET','POST']) def addtocart(): if session.get('userName'): qty = int(request.form.get('qty')) itemID = request.form.get('itemID') dbObj, cur = connectDB() itemData = cur.execute("SELECT * FROM inventory WHERE rowid=?",(itemID,)).fetchone() itemName= itemData['Item'] price = itemData['Price'] available_quantity=itemData['Quantity'] if available_quantity - qty >= 0: available_quantity = available_quantity-qty session['cart'].append([itemName,qty,price*qty]) cur.execute("UPDATE inventory SET Quantity=? WHERE rowid=?",(available_quantity,itemID,)) dbObj.commit() disConnectDB(dbObj, cur) return render_template('addtocart.html', pageTitle='Added to cart', itemName=itemName, quantity=qty) else: disConnectDB(dbObj, cur) return "<h1 style='color:darkorange'>Insufficent quantity! Item cannot be added!</h1><br><a href='/home'>Return to home page</a>" else: return "<h1 style='color:darkorange'>You are not authorized to visit this page!</h1><a href='/home'>Return to login page</a>"
内容的提问来源于stack exchange,提问作者Arun Gopinath
相关产品推荐
相关产品推荐

