DEVANGDIXIT04/disaster-alert
GitHub: DEVANGDIXIT04/disaster-alert
一个基于 Flask 和实时地图的众包灾害预警与响应平台,让民众可以上报突发事件、众包验证并自动通知附近居民。
Stars: 0 | Forks: 0
# 众包灾害预警与响应平台
[](https://github.com/DEVANGDIXIT04/disaster-alert/actions/workflows/ci.yml)




一个由民众驱动的本地突发事件地图。人们可以通过放置图钉并填写一份简短的表单来上报事件(洪水、火灾、事故等);所有人都能看到这些以严重程度着色的实时标记。已登录的用户可以查询**“我附近有什么?”**,**众包验证**事件是否仍在发生,并且每份新报告都会触发一个**serverless function**,计算出需要向哪些附近的居民发送警报。
## 功能
- 🗺️ **实时事件地图** — 点击即可上报;根据严重程度,标记会显示为绿色/橙色/红色;每 30 秒自动刷新。
- 🔐 **账户与 JWT 认证** — 注册/登录时使用哈希密码;只有已登录的用户才能上报或投票。
- 📍 **邻近搜索** — 使用 haversine 公式查询“距离我 X 公里内的事件”。
- 🔔 **Serverless 警报** — 由 AWS Lambda 计算哪些居民住得足够近并需要被通知。
- ✅ **众包验证** — 用户投票决定事件是否仍然存在;多数投票为“已解除”将自动移除该事件。
- ☁️ **云原生** — 同一个镜像可以在本地运行,也可以在配有 Postgres 的 Docker 中运行,或在 AWS 上运行;只需通过一个环境变量即可切换数据库。
## 架构
```
Browser — static/index.html (Leaflet map + vanilla JS)
│ JSON over HTTPS (fetch); JWT in the Authorization header
▼
┌──────────────────────────────────────────────┐ DATABASE_URL selects:
│ Flask REST API — app.py │ ┌────────────────────┐
│ /api/register /api/login [auth.py] │ ───▶ │ SQLite (local) │
│ /api/reports /api/reports/nearby │ │ PostgreSQL (Docker │
│ /api/reports//vote │ │ & Amazon RDS) │
│ serves index.html · gunicorn on AWS │ └────────────────────┘
└──────────────────────────────────────────────┘
│ same logic, two homes
▼
serverless/notify_lambda.py — find_nearby_users()
• imported & called directly by app.py (local path)
• deployed as an AWS Lambda, invoked via boto3 (cloud path)
```
地图 UI 是一个由 Flask 提供服务的单一静态文件;API 是位于 `/api` 下的独立 JSON 接口;通知逻辑是一个可独立部署的单元(体现了微服务/Serverless 的拆分)。
## 技术栈
| 层级 | 选型 | 原因 |
|---|---|---|
| 后端 | Python 3.12 · Flask · Flask-SQLAlchemy | 极简、可读性强、逐行易于解释 |
| 认证 | PyJWT · Werkzeug 密码哈希 | 无状态 token,加盐单向密码哈希 |
| 数据库 | SQLite (开发环境) → PostgreSQL / Amazon RDS (云端) | 本地零配置;云端托管且持久化 —— 代码保持一致 |
| 前端 | Leaflet.js + 原生 JS (CDN) | 无需构建步骤,无需框架 |
| Serverless | AWS Lambda (仅使用标准库的 handler) | 按需运行,在此规模下几乎免费 |
| 容器 | Docker + docker-compose | 到处使用同一个镜像;compose 添加真实的 Postgres |
| 部署服务 | Elastic Beanstalk 上的 gunicorn | 位于托管 nginx 之后的生产级 WSGI 服务器 |
| CI | GitHub Actions | 每次 push 时运行 `pytest` |
## 螺旋迭代日志
采用螺旋模型构建 —— 先实现一个可运行的基础切片,然后进行明确区分的增量增强,每次提交对应一个 git commit,使演进过程清晰可见。
| 版本 | Commit | 新增内容 |
|---|---|---|
| v1 | `v1: report + map` | Flask + SQLite,Report model,GET/POST reports,Leaflet 页面(放置图钉 → 提交 → 显示标记) |
| v2 | `v2: auth + categories` | User model,注册/登录,JWT + `@token_required`,类别和严重程度,彩色标记,pytest 测试套件 |
| v3 | `v3: nearby + serverless + docker + aws` | Haversine + `/reports/nearby`,Lambda(也可在本地运行),Docker + compose (Postgres),`DATABASE_URL` 切换,AWS 部署文档 |
| v4 | `v4: cloud polish` | API 通过 boto3 调用**真实的** Lambda(`notify_source` 验证),种子数据,30 秒自动刷新,速率限制 + 输入限制,GitHub Actions CI |
| v5 | `v5: crowd verification` | Vote model + `/reports//vote`,多数投“已解除”自动移除,弹窗中的投票 UI,输出转义(XSS 加固) |
## 快速开始(本地,3 条命令)
```
pip install -r requirements.txt
python app.py # → http://localhost:5000
# optional: python seed.py (8 demo incidents + demo@example.com / demo123456)
```
SQLite `local.db` 将自动创建。使用 `pytest` 运行测试(共 **24 个测试**)。如果各版本间 Schema 发生变化?删除 `local.db` 即可 —— 它会自动重新创建。
## 使用 Docker + PostgreSQL 运行
```
docker compose up --build # → http://localhost:8000 (app + postgres:16)
```
## API 参考
| 方法与路径 | 认证 | 用途 |
|---|---|---|
| `GET /api/health` | — | 存活状态检查(供 AWS 健康检查使用) |
| `POST /api/register` | — | 创建账户 → 返回 JWT |
| `POST /api/login` | — | 验证身份 → 返回 JWT |
| `GET /api/reports` | — | 列出所有事件 |
| `POST /api/reports` | JWT | 创建事件(+ 返回将被警报的人员) |
| `GET /api/reports/nearby?lat=&lng=&radius_km=` | — | 某半径范围内的事件 |
| `POST /api/reports//vote` | JWT | 投票“仍存在” / “已解除”;多数投“已解除”则自动移除 |
## 部署到 AWS
- Elastic Beanstalk 上的应用 → [deploy/aws-elastic-beanstalk.md](deploy/aws-elastic-beanstalk.md)
- RDS 上的 PostgreSQL → [deploy/aws-rds-setup.md](deploy/aws-rds-setup.md)
- Lambda → [serverless/README.md](serverless/README.md)
## 课程概念覆盖
| 概念 | 所在位置 |
|---|---|
| 云部署 | `Procfile`, `.ebextensions/`, `deploy/aws-elastic-beanstalk.md` |
| RESTful API | `app.py` — 位于 `/api` 下的资源路由,正确的动词和状态码 (200/201/400/401/404/429) |
| 数据库集成 | `models.py` (SQLAlchemy) + `DATABASE_URL` 环境变量切换 (SQLite ↔ PostgreSQL/RDS) |
| 微服务拆分 | `serverless/notify_lambda.py` — 通知是一个独立的可部署单元 |
| Serverless (AWS Lambda) | `serverless/notify_lambda.py`;实时 API 通过 boto3 调用它 — `notify_source` 字段证明了运行的是哪条路径 |
| 容器化 | `Dockerfile`, `docker-compose.yml` (app + postgres:16) |
| 安全 / 认证 | `auth.py` (JWT 签名/验证, `@token_required`),密码哈希,认证速率限制,输出转义 |
## 安全说明
- 密码仅以**加盐哈希**形式存储 (`werkzeug.security`);绝不持久化明文。
- JWT 使用来自 `JWT_SECRET` 的密钥进行 HS256 签名;**24 小后过期**;保存在 JS 变量中,而不是 `localStorage`。
- 登录/注册受到**速率限制**(每个 IP 每分钟 10 次尝试),以减缓密码暴力破解。
- 所有用户提供文本在渲染前均经过 **HTML 转义**(防御存储型 XSS),并在服务端设置了长度限制。
- 邮箱错误与密码错误返回相同的登录错误提示,防止账户被枚举探测。
## 未来范围
通过 Amazon SNS 发送真实 SMS/电子邮件 · 在 S3 中存储报告照片 · 重复/审核检测 · 使用 WebSocket 推送代替轮询 · 使用 PostGIS 进行大规模地理查询 · 使用共享的速率限制/投票存储 (Redis) 以实现多实例扩展。
## 团队
| 姓名 | 学号 |
|---|---|
| Abhijeet Kumar Singh | 22803029 |
| Viyom Shukla | 22803030 |
| Devang Dixit | 22803031 |
**课程:** 云与 Web 服务实验 [17M15CS121] · JIIT, Sector 62
## 许可证
基于 [MIT 许可证](LICENSE) 发布。
标签:AWS Lambda, Docker, Flask, PostgreSQL, 众包平台, 地理信息系统, 安全防御评估, 测试用例, 灾害预警, 请求拦截, 逆向工具