Flask实现带权限的链接共享功能:未注册用户访问特定路由咨询
问题解答
一、功能的标准名称
这个功能通常被称为 公共共享链接(Public Shareable Links),也可称为预授权访问令牌链接,核心是通过生成包含授权凭证的特殊链接,让未认证用户获得特定资源的有限访问权限。
二、安全实现方案(基于你的Flask应用)
1. 数据库新增共享令牌表
在PostgreSQL中创建存储令牌信息的表,绑定用户权限与可访问数据范围:
CREATE TABLE share_tokens ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, token VARCHAR(64) UNIQUE NOT NULL, allowed_data_params JSONB NOT NULL, -- 存储允许访问的特定数据参数(如图表ID、查询条件) expires_at TIMESTAMP, -- 可选:设置令牌过期时间 is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
allowed_data_params:严格限定令牌可访问的数据范围,避免持有者越权访问其他资源。expires_at:建议添加,通过有效期限制令牌泄露后的风险影响时长。
2. 实现共享链接生成接口
给登录用户添加生成令牌的路由,生成带高熵令牌的共享链接:
import secrets from datetime import datetime, timedelta from flask import request, jsonify from your_app import db, login_required from models import ShareToken, current_user @app.route('/generate-share-link', methods=['POST']) @login_required def generate_share_link(): allowed_params = request.get_json().get('allowed_params', {}) if not allowed_params: return jsonify({'error': '请指定允许访问的数据参数'}), 400 # 生成高安全随机令牌 token = secrets.token_urlsafe(32) # 设置7天有效期,可根据需求调整 expires_at = datetime.utcnow() + timedelta(days=7) new_token = ShareToken( user_id=current_user.id, token=token, allowed_data_params=allowed_params, expires_at=expires_at ) db.session.add(new_token) db.session.commit() share_link = f"{request.host_url}plot?share_token={token}" return jsonify({'share_link': share_link})
3. 修改/plot路由的权限验证逻辑
让路由同时支持登录用户认证与共享令牌认证,且严格限制令牌的访问范围:
from flask import request, abort from datetime import datetime from models import ShareToken, current_user @app.route('/plot', methods=['POST']) def plot(): # 优先检查共享令牌 share_token = request.args.get('share_token') if share_token: token_record = ShareToken.query.filter_by(token=share_token, is_active=True).first() if not token_record: abort(403, description='无效的共享链接') # 检查令牌是否过期 if token_record.expires_at and token_record.expires_at < datetime.utcnow(): abort(403, description='共享链接已过期') # 强制使用令牌预定义的参数,防止篡改请求越权 request_params = token_record.allowed_data_params else: # 原有登录验证逻辑 if not current_user.is_authenticated: abort(401, description='请先登录') request_params = request.get_json() # 后续业务逻辑:根据request_params查询数据、渲染Chart.js图表 # ... 你的原有代码 ...
4. 额外安全加固措施
- 令牌撤销功能:给用户添加撤销共享链接的接口,将对应令牌的
is_active设为False即可。 - 最小权限原则:
allowed_data_params仅包含必要的查询条件(如特定图表ID、固定时间范围),避免宽泛的权限设置。 - 强制HTTPS:确保所有请求通过HTTPS传输,防止令牌在网络传输中被窃取。
- 访问日志记录:记录共享链接的访问日志,包括令牌ID、访问时间、IP地址,便于异常排查。
内容的提问来源于stack exchange,提问作者user3141592
相关产品推荐
相关产品推荐

