Flask中Session读取突然失效,触发Key Error问题求助
Flask Session 读取触发KeyError问题解决
问题概述
开发计算机课程预订网站时,使用Flask Session在两个页面间传递预订数据,已通过日志确认数据存入第一个路由的Session,但在第二个路由读取时触发KeyError,无法获取数据。
相关代码
@app.route("/manager/editbooking", methods=["POST", "GET"]) def managereditbooking(): if request.method == "POST": if "Filter" in request.form != "Filter": StartDate = request.form.get("StartDate") EndDate = request.form.get("EndDate") Filter = request.form.get("Filter") app.logger.info(f"{StartDate} {EndDate} {Filter}") if Filter == "all" and StartDate and EndDate: # Filter by date range getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.Extra, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Booking.Date BETWEEN '{StartDate}' AND '{EndDate}' ORDER BY Booking.Date ASC" elif Filter != "all" and StartDate and EndDate: # Filter by type and date range getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults , Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionType = '{Filter}' AND Booking.Date BETWEEN '{StartDate}' AND '{EndDate}' ORDER BY Booking.Date ASC" elif Filter != "all": # Filter by type only if Filter == "Private Hire": getactivebookings = "SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults , Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionID = 8 OR Session.SessionID = 9 OR Session.SessionID = 10 ORDER BY Booking.Date ASC" else: getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults , Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionType = '{Filter}' ORDER BY Booking.Date ASC" elif StartDate and EndDate: # Filter by date range only getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Booking.Date BETWEEN '{StartDate}' AND '{EndDate}' ORDER BY Booking.Date ASC" else: getactivebookings = "SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID ORDER BY Booking.Date ASC" app.logger.info(getactivebookings) q.execute(getactivebookings) activebookings = q.fetchall() return render_template("manager/selectbooking.html", activebookings=activebookings) else: app.logger.info("Redirecting to booking page") BookingID = request.form["BookingID"] BookingDate = request.form["BookingDate"] BookingTime = request.form["BookingTime"] SessionType = request.form["SessionType"] Extra = request.form["Extra"] BookingPrice = request.form["BookingPrice"] NumberAdults = request.form["NumberAdults"] NumberChildren = request.form["NumberChildren"] FirstName = request.form["FirstName"] LastName = request.form["LastName"] session["BookingID"] = BookingID session["BookingPrice"] = BookingPrice session["BookingDate"] = BookingDate session["BookingTime"] = BookingTime session["SessionType"] = SessionType session["NumberAdults"] = NumberAdults session["NumberChildren"] = NumberChildren session["Extra"] = Extra session["FirstName"] = FirstName session["LastName"] = LastName return redirect(url_for("managerbooking")) else: try: getactivebookings = "SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID ORDER BY Booking.Date ASC" q.execute(getactivebookings) activebookings = q.fetchall() app.logger.info(activebookings) return render_template("manager/selectbooking.html", activebookings=activebookings) except Exception as error: return render_template("error.html", error=error) @app.route("/manager/managebooking/booking", methods=["POST", "GET"]) def managerbooking(): BookingID = session["BookingID"] BookingDate = session["BookingDate"] BookingTime = session["BookingTime"] SessionType = session["SessionType"] Extra = session["Extra"] BookingPrice = session["BookingPrice"] NumberAdults = session["NumberAdults"] NumberChildren = session["NumberChildren"] FirstName = session["FirstName"] LastName = session["LastName"] if request.method == "POST": app.logger.info(f"Deleting Booking with Booking ID: {BookingID}") DeleteBooking = "DELETE FROM Booking WHERE BookingID = (?)" try: q.execute(DeleteBooking, [BookingID]) sql.commit() app.logger.info("Booking Deleted Succesfully") return redirect(url_for("managereditbooking")) except Exception as error: return render_template("/error.html", error=error) else: return render_template("manager/booking.html", BookingID = BookingID, BookingDate = BookingDate, BookingTime = BookingTime, Extra = Extra, SessionType = SessionType, BookingPrice = BookingPrice, NumberAdults = NumberAdults, NumberChildren = NumberChildren, FirstName = FirstName, LastName = LastName)
解决步骤
1. 确认SECRET_KEY配置
Flask Session依赖SECRET_KEY进行加密存储,没有配置的话Session数据无法持久化。在Flask应用初始化时添加:
import secrets app.secret_key = secrets.token_hex(16) # 生成安全的随机密钥
生产环境要将密钥存入环境变量,不要硬编码到代码中。
2. 强制标记Session修改
在存入Session数据后,手动设置session.modified = True确保数据被保存到会话中,避免重定向时数据丢失:
# 在重定向前添加 session["LastName"] = LastName session.modified = True # 新增这行 return redirect(url_for("managerbooking"))
3. 检查键名一致性
确认存入和读取Session的键名完全一致,比如session["BookingID"]和读取时的session["BookingID"],注意大小写和拼写,避免因键名错误触发KeyError。
4. 验证Cookie可用性
Flask Session通过Cookie传递会话ID,检查浏览器是否禁用了Cookie,测试时使用同一个浏览器窗口,不要开启隐私模式。
5. 防御SQL注入(额外建议)
当前代码使用字符串拼接SQL语句,存在严重的SQL注入风险,即使先实现功能,也建议尽快改用参数化查询,示例:
# 替换原字符串拼接的SQL getactivebookings = """ SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionType = ? AND Booking.Date BETWEEN ? AND ? ORDER BY Booking.Date ASC """ q.execute(getactivebookings, (Filter, StartDate, EndDate))
内容的提问来源于stack exchange,提问作者Ben Mercer
相关产品推荐
相关产品推荐

