网站首页/ 信息中心/ 档案百科/

手把手教你搭建档案管理系统并实现永久授权

发布时间:2026年07月03日 11:00:23 浏览量:0

一、技术栈选择与环境准备

为了确保系统的轻量化和易部署性,本指南采用 Python 语言进行开发。我们将使用 Flask 作为 Web 框架,SQLite 作为数据库(无需额外安装数据库服务),并利用 JWT(JSON Web Token)技术来实现永久授权机制。这种方式无需复杂的加密狗硬件,纯软件实现,代码完全可控。

1. 安装基础依赖

确保你的系统中安装了 Python 3.8 或更高版本。打开终端,依次执行以下命令安装必要的系统库和 Python 包:

Ubuntu/Debian 系统执行:

```bash sudo apt-get update sudo apt-get install python3 python3-pip python3-venv -y ```

CentOS/RHEL 系统执行:

```bash sudo yum install python3 python3-pip -y ```

Windows 系统请直接从 python.org 下载安装包并勾选 "Add Python to PATH"。

2. 创建项目目录并初始化虚拟环境

为了隔离项目依赖,我们创建一个独立的目录并初始化虚拟环境。执行以下命令:

```bash mkdir archive_system cd archive_system python3 -m venv venv source venv/bin/activate Windows下使用 venv\Scripts\activate ```

3. 安装 Python 核心依赖包

激活虚拟环境后,安装 Flask、JWT 扩展包以及工具库:

```bash pip install flask flask-sqlalchemy flask-jwt-extended pyjwt cryptography ```

安装完成后,创建 requirements.txt 文件以便后续环境复现:

```bash pip freeze > requirements.txt ```

二、项目目录结构设计

archive_system 根目录下,按照以下结构创建文件夹和文件。这种结构清晰分离了配置、模型、业务逻辑和授权模块:

```text archive_system/ ├── app.py 程序入口与路由逻辑 ├── config.py 配置文件(密钥与数据库路径) ├── auth_service.py 授权核心逻辑(生成与验证永久License) ├── models.py 数据库模型定义 ├── storage/ 档案文件存储目录 └── requirements.txt 依赖列表 ```

执行命令创建 storage 目录:

```bash mkdir storage ```

三、核心授权模块开发(实现永久授权)

这是本系统的核心。我们将使用非对称加密(RSA)或者高强度对称加密(HMAC)来签发 License。为了演示“永久授权”,我们将生成一个包含过期时间字段设置为“永不过期”的 JWT Token。

创建并编辑 auth_service.py,写入以下代码:

```python import jwt from datetime import datetime, timedelta from flask import jsonify 密钥配置:在生产环境中,请务必将此密钥存储在环境变量或受保护的配置文件中 SECRET_KEY = "ARCHIVE_SYSTEM_SUPER_SECRET_KEY_2024" def generate_permanent_license(client_id): """ 生成永久授权 License :param client_id: 客户端唯一标识(如机器码或公司ID) :return: 加密后的 License 字符串 """ 永久授权的核心在于将过期时间设置得非常久,或者不设置 exp 字段(视解析逻辑而定) 这里为了兼容性,设置为 100 年后过期 expiry_time = datetime.utcnow() + timedelta(days=365 100) payload = { "client_id": client_id, "type": "permanent", 授权类型标记 "scope": "full_access", 权限范围 "exp": expiry_time } 使用 HS256 算法进行签名 token = jwt.encode(payload, SECRET_KEY, algorithm="HS256") return token def validate_license(token): """ 验证 License 的有效性 :param token: 客户端提交的 License :return: (bool, dict) 验证结果和解码后的数据 """ try: decode 会自动验证 exp (过期时间) payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) 额外检查是否为永久授权类型 if payload.get("type") == "permanent": return True, payload else: return False, {"error": "非永久授权 License"} except jwt.ExpiredSignatureError: return False, {"error": "License 已过期"} except jwt.InvalidTokenError: return False, {"error": "无效的 License"} ```

四、数据库模型设计

我们需要一个数据表来存储上传的档案元数据(文件名、上传时间、存储路径等)。创建并编辑 models.py

```python from flask_sqlalchemy import SQLAlchemy from datetime import datetime db = SQLAlchemy() class ArchiveFile(db.Model): __tablename__ = 'archive_files' id = db.Column(db.Integer, primary_key=True) filename = db.Column(db.String(255), nullable=False) 原始文件名 stored_path = db.Column(db.String(500), nullable=False) 磁盘存储路径 file_size = db.Column(db.Integer) 文件大小(字节) upload_time = db.Column(db.DateTime, default=datetime.utcnow) 上传时间 uploader = db.Column(db.String(100)) 上传者标识 def to_dict(self): return { "id": self.id, "filename": self.filename, "file_size": self.file_size, "upload_time": self.upload_time.strftime("%Y-%m-%d %H:%M:%S"), "uploader": self.uploader } ```

五、配置文件与主程序逻辑

创建 config.py,设置数据库 URI 和上传文件夹限制:

```python import os basedir = os.path.abspath(os.path.dirname(__file__)) class Config: 使用 SQLite 数据库,文件名为 data.db SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data.db') SQLALCHEMY_TRACK_MODIFICATIONS = False 文件上传配置:最大 100MB MAX_CONTENT_LENGTH = 100 1024 1024 UPLOAD_FOLDER = os.path.join(basedir, 'storage') ```

手把手教你搭建档案管理系统并实现永久授权

接下来是核心业务逻辑 app.py。这里我们将整合授权验证、文件上传和列表查询功能:

```python import os import uuid from flask import Flask, request, jsonify, send_from_directory from werkzeug.utils import secure_filename 导入自定义模块 from config import Config from models import db, ArchiveFile from auth_service import validate_license app = Flask(__name__) app.config.from_object(Config) 初始化数据库 db.init_app(app) 允许的文件扩展名 ALLOWED_EXTENSIONS = {'pdf', 'doc', 'docx', 'txt', 'jpg', 'png', 'zip'} def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS 装饰器:用于保护需要授权的接口 def license_required(f): def decorated_function(args, kwargs): 从请求头获取 License auth_header = request.headers.get('Authorization') if not auth_header: return jsonify({"error": "未提供 License,请在 Header 中添加 Authorization 字段"}), 401 假设 Header 格式为 "Bearer " token = auth_header.split(" ")[1] if " " in auth_header else auth_header is_valid, payload = validate_license(token) if not is_valid: return jsonify({"error": payload.get("error"), "code": 403}), 403 将 payload 信息存入请求上下文,供后续使用 request.current_user = payload.get("client_id") return f(args, kwargs) return decorated_function @app.route('/api/upload', methods=['POST']) @license_required def upload_file(): if 'file' not in request.files: return jsonify({"error": "未找到文件部分"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "未选择文件"}), 400 if file and allowed_file(file.filename): 安全处理文件名,防止路径遍历攻击 filename = secure_filename(file.filename) 生成唯一文件名防止覆盖 unique_filename = f"{uuid.uuid4().hex}_{filename}" save_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename) file.save(save_path) 存入数据库 new_file = ArchiveFile( filename=filename, stored_path=save_path, file_size=os.path.getsize(save_path), uploader=request.current_user ) db.session.add(new_file) db.session.commit() return jsonify({"message": "上传成功", "file_id": new_file.id}), 201 else: return jsonify({"error": "不支持的文件类型"}), 400 @app.route('/api/files', methods=['GET']) @license_required def list_files(): 分页查询 page = request.args.get('page', 1, type=int) per_page = request.args.get('per_page', 10, type=int) pagination = ArchiveFile.query.paginate(page=page, per_page=per_page, error_out=False) files_list = [item.to_dict() for item in pagination.items] return jsonify({ "files": files_list, "total": pagination.total, "pages": pagination.pages }) @app.route('/api/download/', methods=['GET']) @license_required def download_file(file_id): file_record = ArchiveFile.query.get(file_id) if not file_record: return jsonify({"error": "文件不存在"}), 404 if os.path.exists(file_record.stored_path): return send_from_directory( os.path.dirname(file_record.stored_path), os.path.basename(file_record.stored_path), as_attachment=True, download_name=file_record.filename ) else: return jsonify({"error": "物理文件已丢失"}), 404 初始化数据库表 with app.app_context(): db.create_all() if __name__ == '__main__': 启动服务,监听所有 IP,端口 5000 app.run(host='0.0.0.0', port=5000, debug=True) ```

六、生成永久授权 License

系统部署后,我们需要生成一个 License 给客户端使用。我们可以编写一个简单的脚本或直接在 Python 交互式环境中生成。为了方便操作,我们在项目根目录创建一个临时脚本 gen_license.py

```python from auth_service import generate_permanent_license 输入客户端标识,可以是公司名或服务器 ID client_id = input("请输入客户端标识 (例如: CLIENT_001): ") license_key = generate_permanent_license(client_id) print("-" 50) print(f"客户端: {client_id}") print(f"永久授权 License: {license_key}") print("-" 50) print("请妥善保存此 License,并在 API 请求头 Authorization 中使用。") ```

运行该脚本:

```bash python gen_license.py ```

输入标识后,你将获得一长串加密字符串,这就是该系统的永久授权密钥。只要服务端 SECRET_KEY 不变,该 License 永久有效。

七、系统启动与接口实操测试

所有代码准备就绪,现在启动系统并进行实际操作测试。

1. 启动服务

```bash python app.py ```

看到输出 Running on http://0.0.0.0:5000 表示启动成功。

2. 测试文件上传(模拟 POST 请求)

我们需要使用生成的 License。假设生成的 License 是 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...。我们在终端使用 curl 命令测试上传一个测试文件 test.txt:

```bash 先创建一个测试文件 echo "This is a secret archive file." > test.txt 执行上传命令 curl -X POST http://127.0.0.1:5000/api/upload \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \ -F "file=@test.txt" ```

预期返回结果:

```json { "file_id": 1, "message": "上传成功" } ```

3. 测试文件列表查询(验证授权拦截)

如果不带 Header 访问,应该返回 401 错误:

```bash curl http://127.0.0.1:5000/api/files ```

预期返回结果:

```json {"code": 403, "error": "未提供 License,请在 Header 中添加 Authorization 字段"} ```

带上正确的 Header 访问:

```bash curl http://127.0.0.1:5000/api/files \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." ```

预期返回结果:

```json { "files": [ { "file_size": 30, "filename": "test.txt", "id": 1, "upload_time": "2024-05-20 10:30:00", "uploader": "CLIENT_001" } ], "pages": 1, "total": 1 } ```

八、部署与持久化建议

以上步骤完成了从零到一的搭建。为了在生产环境中长期稳定运行,请注意以下最后两个关键点:

  • 数据备份: 系统使用 SQLite 数据库,文件为 data.db,档案文件存储在 storage/ 目录。请务必设置定时任务(如 Cron)将这两个目录打包备份到远程存储或 NAS。
  • 进程守护: 不要直接使用 python app.py 在前台运行。建议使用 supervisorsystemd 将 Flask 进程守护,确保服务器重启后服务自动拉起。

至此,你已拥有一个完全自主可控、基于 Token 永久授权的档案管理系统。无需向任何厂商支付年费,License 即生成即永久有效。

档案管理软件企业云部署 中小企业数字化升级的高性价比选择
档案管理软件企业云部署 中小企业数字化升级的高性价比选择
说真的各位老板、行政岗、IT岗的兄弟姐妹们,我去年帮公司搞数字化升级的时候,在档案管理这块踩的坑能绕公司茶水间三圈,最后摸着石头过河选了档案管理软件企业云部署,才把这堆烂摊子给捋明白,今天掏心窝子给你...
2026年07月03日 11:00:23
微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818