You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-Session问题:同一浏览器下不同用户购物车数据串扰排查

问题描述

我开发了一个包含用户登录和购物车功能的小型Flask应用,使用Flask-Session扩展和SQLite3。遇到的问题如下:在同一浏览器中,以用户A登录并向购物车添加商品,退出后登录用户B(未关闭浏览器),此时查看B的购物车,仍能看到用户A添加的商品,但预期应为空购物车。

错误原因

问题出在会话清理不彻底和购物车初始化逻辑漏洞:

  • 退出登录时仅移除了userName会话变量,但cart变量仍保留在会话中,导致新用户登录时直接复用旧购物车数据。
  • 登录逻辑中仅在cart不存在时才初始化空列表,但如果会话中已有旧的cart数据,就不会重新初始化,直接继承了上一个用户的购物车内容。
修复方案
  1. 退出登录时,同步清理会话中的购物车数据,或直接清空整个会话。
  2. 登录成功后,强制初始化当前用户的空购物车,覆盖可能存在的旧数据。
修改后的完整代码
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:20:53