diff --git a/src/flask_prompt_master/routes/api_service.py b/src/flask_prompt_master/routes/api_service.py index 1f3c10d..c71d0ac 100644 --- a/src/flask_prompt_master/routes/api_service.py +++ b/src/flask_prompt_master/routes/api_service.py @@ -379,6 +379,62 @@ def api_docs_page(): return render_template('api_docs.html') +@api_service_bp.route('/api-key/apply', methods=['GET']) +def apikey_apply_page(): + """自助申请 API Key 页面""" + return render_template('apikey_apply.html') + + +@api_service_bp.route('/api/api-key/apply', methods=['POST']) +def apikey_apply_api(): + """自助申请 API Key(公开接口,有创建频率限制)""" + # 独立的创建频率限制:每 IP 每分钟最多 1 次 + client_ip = request.remote_addr or 'unknown' + create_key = f'create_{client_ip}' + now = time.time() + create_bucket = _rate_buckets.setdefault(create_key, []) + create_bucket[:] = [ts for ts in create_bucket if now - ts < 60] + if create_bucket: + return jsonify({'code': 429, 'message': '每个IP每分钟只能申请1个密钥,请稍后再试'}) + create_bucket.append(now) + + try: + from src.flask_prompt_master.models.models import ApiKey + from src.flask_prompt_master import db + + payload = request.get_json() or {} + name = (payload.get('name') or '').strip() + email = (payload.get('email') or '').strip() + + if not name: + return jsonify({'code': 400, 'message': '请填写您的名称'}) + + label = name + if email: + label += f' ({email})' + + # 生成 key + key = 'sk-' + secrets.token_hex(24) + + k = ApiKey(key=key, label=label) + db.session.add(k) + db.session.commit() + + logger.info("用户自助申请 API Key: %s -> key=%s", label, key[:12] + '...') + return jsonify({ + 'code': 200, + 'message': '申请成功', + 'data': { + 'key': key, + 'label': label, + 'docs_url': '/api-docs' + } + }) + except Exception as e: + logger.exception("自助申请 API Key 失败") + return jsonify({'code': 500, 'message': str(e)}) + + # ===== API Key 管理页面 ===== @api_service_bp.route('/admin/apikeys', methods=['GET']) diff --git a/src/flask_prompt_master/templates/api_docs.html b/src/flask_prompt_master/templates/api_docs.html index 97764be..dcb4c10 100644 --- a/src/flask_prompt_master/templates/api_docs.html +++ b/src/flask_prompt_master/templates/api_docs.html @@ -19,11 +19,15 @@ +
前往自助申请页面,填写名称即可立即获取密钥,无需审核。
+在请求头中携带 X-API-Key:
X-API-Key: sk-your-api-key
- 联系管理员获取 API 密钥。
免费申请,即时生效。用于调用提示词优化接口。
+