如何让Flask编写的Rest API仅对Android应用注册页开放?
关于Flask做Android后端API及接口安全的解决方案
先明确:Python Flask完全适合为Android应用开发Rest API
Flask轻量灵活,开发成本低、部署简单,很多中小型移动端项目的后端都是用Flask搭建的,完全能满足Android应用的API需求,不用有顾虑。
解决POST接口被任意访问的安全方案
针对你的问题,下面是几种实用的方案,能让接口只对你的Android应用开放:
1. 嵌入API密钥验证
在你的Android应用中嵌入一个唯一的API密钥,每次请求POST接口时,在请求头里带上这个密钥,Flask后端验证密钥的合法性:
- Android端请求时,添加请求头
X-API-Key: 你的唯一密钥 - Flask端修改代码验证:
from flask import request, jsonify # 预设的API密钥,要和Android端一致,建议通过环境变量读取,不要硬编码在公开代码里 VALID_API_KEY = "your_unique_secret_key_here" @app.route('/user/', methods=['GET','POST']) def user_page(): if request.method == 'GET': id_parameter = request.args.get('id') if not id_parameter: return jsonify({'Error':'Invalid parameter(s)'}) user = getUserById(id_parameter) if not user: return jsonify({'Error':'Invalid parameter(s)'}) return jsonify({ 'UserID':user.id, 'Username':user.username # 注意!这里绝对不能返回明文密码,这是严重的安全漏洞! }) elif request.method == 'POST': # 先验证API密钥 api_key = request.headers.get('X-API-Key') if api_key != VALID_API_KEY: return jsonify({'Error':'Unauthorized'}), 401 # 建议POST用request.get_json()或request.form获取参数,而非request.args(GET参数用args) username = request.get_json().get('username') password = request.get_json().get('password') # 若用表单提交则改为:username = request.form.get('username') if not username or not password: return jsonify({'Error':'Missing parameters'}), 400 insertUsers(username, password) return jsonify({'Status':'SUCCESS'}), 201
注意:API密钥不要直接硬编码在Android应用代码里,可以通过代码混淆、本地加密或者后端动态下发的方式处理,防止被反编译提取。
2. 请求签名验证(更安全)
比单纯的API密钥更安全,能防止密钥被抓包后滥用。核心逻辑是:
- Android端将请求参数、当前时间戳用约定的密钥生成签名
- 把时间戳和签名一起放在请求头里发送
- Flask端按相同规则生成签名,对比是否一致,同时验证时间戳是否在有效范围内(防止重放攻击)
示例代码:
import hmac import hashlib from datetime import datetime SECRET_KEY = "your_shared_secret" ALLOWED_TIME_DIFF = 300 # 允许的时间差(秒),比如5分钟 def verify_signature(timestamp, signature, data): # 生成待签名字符串:时间戳+原始请求数据 sign_string = f"{timestamp}{data}" # 用HMAC-SHA256生成签名 expected_sign = hmac.new(SECRET_KEY.encode(), sign_string.encode(), hashlib.sha256).hexdigest() # 验证签名+时间戳有效性 now = datetime.now().timestamp() if abs(now - float(timestamp)) > ALLOWED_TIME_DIFF: return False return hmac.compare_digest(expected_sign, signature) @app.route('/user/', methods=['POST']) def user_page(): timestamp = request.headers.get('X-Timestamp') signature = request.headers.get('X-Signature') data = request.get_data(as_text=True) # 获取原始请求数据 if not timestamp or not signature or not verify_signature(timestamp, signature, data): return jsonify({'Error':'Unauthorized'}), 401 # 后续参数处理及插入逻辑...
Android端需要实现对应的签名生成逻辑,确保和后端规则完全一致。
3. 辅助手段:验证User-Agent(仅作为补充)
可以在请求头里设置自定义的User-Agent,后端验证是否匹配,但这个容易伪造,只能作为辅助安全措施:
VALID_USER_AGENT = "YourAndroidApp/1.0.0" if request.headers.get('User-Agent') != VALID_USER_AGENT: return jsonify({'Error':'Unauthorized'}), 401
内容的提问来源于stack exchange,提问作者asodisc
相关产品推荐
相关产品推荐

