Flask如何修改路由URL 解决参数篡改引发页面内容变动问题
问题根因
当前实现把用户名作为动态路径参数绑定在用户主页路由上,一方面路由规则强制要求传入usr参数才能匹配,缺失就会抛参数错误;另一方面路径参数完全由用户可控,手动修改URL就会直接改变页面渲染内容,完全没有身份校验逻辑。
要实现需求,核心是放弃URL传参的方案,改用Flask原生的session服务端会话存储登录用户身份,用户无法通过修改URL篡改服务端存储的会话数据。
修改步骤
- 配置Flask必填的
SECRET_KEY,session的签名加密依赖该配置 - 登录校验通过后,将用户名写入服务端session,跳转时不再向URL拼接用户参数
- 修改蓝图路由规则,移除动态路径参数,页面渲染时直接从session读取登录用户名,同时增加未登录访问的拦截逻辑
完整修改后代码
主应用代码
from flask import Flask, request, redirect, url_for, render_template, session app = Flask(__name__) # session加密密钥,生产环境请替换为复杂随机字符串,从环境变量读取不要硬编码 app.config['SECRET_KEY'] = 'your_secure_random_secret_key_here' # 临时演示用用户存储,生产环境请替换为数据库持久化存储 user_storage = [] def signup(fname, email, password): user = { "name": fname, "email": email, "password": password } user_storage.append(user) @app.route('/', methods =["GET", "POST"]) def login(): if request.method == "POST": name = request.form.get("fname") email = request.form.get("email") password = request.form.get('password') signup(name, email, password) # 登录成功后将用户名写入服务端session session['username'] = name # 跳转时不再传递URL路径参数 return redirect(url_for('user_blueprint.main')) return render_template('form.html') # 注册蓝图的代码保持原有逻辑即可 # from your_blueprint_file import user # app.register_blueprint(user, url_prefix='/user')
蓝图代码
from flask import Blueprint, session, redirect, url_for user = Blueprint('user_blueprint', __name__) # 移除路由上的<usr>动态参数,路径固定,不需要用户传入任何参数 @user.route('/main') def main(): # 从服务端session读取登录用户名,用户无法通过URL修改该值 login_username = session.get('username') # 未登录状态访问直接跳回登录页,避免空值报错 if not login_username: return redirect(url_for('login')) return f'Hello {login_username}'
修改后效果
- 登录跳转后URL固定为
ip/user/main,不再携带用户名参数,不存在篡改路径内容的入口 - 访问该路由不需要传入任何路径参数,不会触发参数缺失报错
- 页面展示的用户名从服务端session读取,Flask会对session做签名校验,用户无法自行篡改session内存储的身份信息
- 未登录用户直接访问该地址会自动跳转到登录页,不会出现异常
生产环境优化提示:当前代码为适配原有业务逻辑做了最小改动,正式上线前请补充三点逻辑:一是注册接口增加参数合法性校验,二是用户密码必须用bcrypt、Argon2等算法哈希后存储,禁止明文保存密码;三是
SECRET_KEY必须使用随机生成的长字符串,从环境变量读取,不要硬编码在代码仓库中。
内容的提问来源于stack exchange,提问作者Federico Garcia
相关产品推荐
相关产品推荐

