如何防止用户篡改重发Ajax POST请求至Flask应用伪造数据?
防止Flask地理定位请求伪造的可行方案
针对你遇到的「用户篡改Geolocation坐标后重发POST请求录入虚假数据」的问题,结合你提到的现有方案缺陷,这里给出几个实用的解决思路:
绑定一次性授权令牌到会话
核心思路是让合法的坐标提交必须和「用户授权获取定位」这个行为绑定,且令牌只能用一次:- 前端在用户授权定位成功后,先向Flask请求一个一次性定位令牌;
- 后端生成随机UUID存入用户会话,返回给前端;
- 前端携带坐标和令牌一起POST到
/submit_location; - 后端验证令牌与会话中的值匹配,验证通过后立即销毁会话中的令牌(防止复用)。
代码示例:
后端(Flask):from flask import session, jsonify, request import uuid @app.route('/get_location_token', methods=['GET']) def get_location_token(): # 无登录场景下用临时会话标识用户,已登录可直接用用户ID if 'session_id' not in session: session['session_id'] = str(uuid.uuid4()) # 生成一次性令牌 token = str(uuid.uuid4()) session['location_token'] = token return jsonify({'token': token}) @app.route('/submit_location', methods=['POST']) def submit_location(): data = request.get_json() submitted_token = data.get('token') # 验证令牌并立即销毁,避免重复使用 if submitted_token != session.pop('location_token', None): return jsonify({'error': '无效或重复使用的请求'}), 403 # 处理坐标存储逻辑 save_coords(data['lat'], data['lng']) return jsonify({'status': 'success'})前端JS:
navigator.geolocation.getCurrentPosition(async (pos) => { try { // 获取一次性令牌 const tokenResp = await fetch('/get_location_token'); const tokenData = await tokenResp.json(); // 提交坐标和令牌 await fetch('/submit_location', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ lat: pos.coords.latitude, lng: pos.coords.longitude, token: tokenData.token }) }); } catch (err) { console.error('提交失败:', err); } }, (err) => { console.error('定位授权失败:', err); });校验坐标的合理性
即使令牌验证通过,也可以给坐标加一层合理性校验:- 限制坐标在业务允许的地理范围内(比如服务只覆盖国内,就直接拒绝境外坐标);
- 结合
position.coords.accuracy字段,拒绝精度过低的坐标(比如精度大于1000米,说明定位结果不可靠); - 如果有用户历史位置数据,可检查是否存在不合理的位置跳转(比如1分钟内跨越大半个国家)。
带时效性的请求签名
可以在后端生成包含会话ID、时间戳的HMAC签名,前端提交时必须携带该签名:- 前端请求令牌时,后端同时返回签名(用后端环境变量中的密钥生成,比如
hmac.new(SECRET_KEY, f"{session_id}{timestamp}".encode(), hashlib.sha256).hexdigest()); - 前端提交坐标时,附带签名和时间戳;
- 后端重新计算签名比对,同时检查时间戳是否在有效期内(比如5分钟),防止旧请求被重发。
- 前端请求令牌时,后端同时返回签名(用后端环境变量中的密钥生成,比如
前端行为校验辅助
可以在前端记录一些用户操作轨迹(比如触发定位的按钮点击时间、页面停留时长),随请求一起提交,后端验证这些行为是否符合正常逻辑——比如禁止页面加载后立即提交坐标,避免脚本自动伪造请求。
这些方案组合起来,能大幅提高伪造请求的成本,同时避开你提到的现有方案的缺陷。
内容的提问来源于stack exchange,提问作者Nils Deschrijver
相关产品推荐
相关产品推荐

