# 统一认证 **Repository Path**: hadlooop/login ## Basic Information - **Project Name**: 统一认证 - **Description**: 统一认证 111111 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-01-17 - **Last Updated**: 2025-11-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Django 统一认证系统 (SSO) 基于 Django 框架实现的统一认证系统,支持以手机号为唯一标识的用户认证,并提供单点登录(SSO)功能,允许下游系统免登录访问。 ## 功能特性 - ✅ 基于手机号的用户认证系统 - ✅ JWT Token 认证 - ✅ 单点登录(SSO)支持 - ✅ 下游系统免登录跳转 - ✅ RESTful API 接口 - ✅ CORS 跨域支持 ## 技术栈 - Django 4.2.7 - Django REST Framework 3.14.0 - PyJWT 2.8.0 - MySQL ## 快速开始 ### 1. 安装依赖 **注意**: 安装 MySQL 驱动可能需要系统依赖。在 macOS 上: ```bash brew install mysql-client export PATH="/usr/local/opt/mysql-client/bin:$PATH" ``` 在 Ubuntu/Debian 上: ```bash sudo apt-get install default-libmysqlclient-dev ``` 然后安装 Python 依赖: ```bash pip install -r requirements.txt ``` ### 2. 配置环境变量 复制 `env.example` 为 `.env` 并修改配置: ```bash cp env.example .env ``` **重要**: 编辑 `.env` 文件,配置 MySQL 数据库连接信息: - `DB_NAME`: 数据库名称 - `DB_USER`: 数据库用户名 - `DB_PASSWORD`: 数据库密码 - `DB_HOST`: 数据库主机(默认: localhost) - `DB_PORT`: 数据库端口(默认: 3306) ### 3. 创建 MySQL 数据库 在 MySQL 中创建数据库: ```sql CREATE DATABASE sso_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` ### 4. 数据库迁移 ```bash python manage.py makemigrations python manage.py migrate ``` ### 5. 创建超级用户 ```bash python manage.py createsuperuser ``` ### 6. 运行开发服务器 ```bash python manage.py runserver ``` ## API 接口文档 ### 用户认证接口 #### 1. 用户注册 - **URL**: `/api/auth/register/` - **方法**: `POST` - **请求体**: ```json { "phone": "13800138000", "password": "password123", "password_confirm": "password123", "nickname": "用户昵称", "email": "user@example.com" } ``` #### 2. 用户登录 - **URL**: `/api/auth/login/` - **方法**: `POST` - **请求体**: ```json { "phone": "13800138000", "password": "password123" } ``` - **响应**: ```json { "message": "登录成功", "token": "eyJ0eXAiOiJKV1QiLCJhbGc...", "user": { "id": 1, "phone": "13800138000", "nickname": "用户昵称", "email": "user@example.com" } } ``` #### 3. 获取用户信息 - **URL**: `/api/auth/user/info/` - **方法**: `GET` - **Headers**: `Authorization: Bearer ` #### 4. 用户登出 - **URL**: `/api/auth/logout/` - **方法**: `POST` - **Headers**: `Authorization: Bearer ` ### SSO 接口 #### 1. 生成 SSO Token - **URL**: `/api/auth/sso/generate/` - **方法**: `POST` - **Headers**: `Authorization: Bearer ` - **请求体**: ```json { "system_name": "system1", "redirect_url": "http://downstream-system.com/callback" } ``` - **响应**: ```json { "token": "sso_token_string", "redirect_url": "http://downstream-system.com/callback", "expires_at": "2024-01-01T12:00:00Z" } ``` #### 2. SSO 回调验证 - **URL**: `/api/auth/sso/callback/?token=` - **方法**: `GET` - **说明**: 验证 SSO Token 后自动跳转到下游系统,并在 URL 中携带 JWT Token #### 3. 验证 Token - **URL**: `/api/auth/sso/verify/` - **方法**: `POST` - **请求体**: ```json { "token": "jwt_token_string" } ``` - **响应**: ```json { "valid": true, "user": { "id": 1, "phone": "13800138000", "nickname": "用户昵称" } } ``` ## SSO 使用流程 ### 1. 用户已登录统一认证系统 用户首先在统一认证系统中登录,获得 JWT Token。 ### 2. 访问下游系统 用户访问下游系统时,下游系统检测到用户未登录,重定向到统一认证系统: ``` http://sso-system.com/api/auth/sso/generate/ ``` ### 3. 生成 SSO Token 统一认证系统验证用户身份后,生成一次性 SSO Token(5分钟有效)。 ### 4. 跳转到回调地址 下游系统重定向用户到: ``` http://sso-system.com/api/auth/sso/callback/?token= ``` ### 5. 验证并跳转 统一认证系统验证 SSO Token,生成 JWT Token,然后重定向到下游系统的回调地址: ``` http://downstream-system.com/callback?token= ``` ### 6. 下游系统验证 Token 下游系统从 URL 参数中获取 JWT Token,调用验证接口: ``` POST http://sso-system.com/api/auth/sso/verify/ { "token": "" } ``` 验证成功后,下游系统可以创建本地会话,实现免登录。 ## 配置说明 ### settings.py 关键配置 - `SSO_ALLOWED_SYSTEMS`: 允许的下游系统名称列表 - `JWT_EXPIRATION_DELTA`: JWT Token 过期时间(秒) - `CORS_ALLOWED_ORIGINS`: 允许跨域访问的源地址 ### 环境变量 在 `.env` 文件中配置: **数据库配置(MySQL)**: - `DB_NAME`: 数据库名称(默认: `sso_db`) - `DB_USER`: 数据库用户名(默认: `root`) - `DB_PASSWORD`: 数据库密码 - `DB_HOST`: 数据库主机(默认: `localhost`) - `DB_PORT`: 数据库端口(默认: `3306`) **其他配置**: - `SECRET_KEY`: Django 密钥 - `JWT_SECRET_KEY`: JWT 签名密钥 - `SSO_ALLOWED_SYSTEMS`: 允许的下游系统(逗号分隔) - `CORS_ALLOWED_ORIGINS`: 允许的跨域源(逗号分隔) ## 安全建议 1. **生产环境配置**: - 修改 `SECRET_KEY` 和 `JWT_SECRET_KEY` - 设置 `DEBUG=False` - 使用 HTTPS 2. **Token 安全**: - JWT Token 有效期建议设置为合理时间(如 7 天) - SSO Token 为一次性使用,5 分钟过期 3. **系统白名单**: - 在 `SSO_ALLOWED_SYSTEMS` 中只添加信任的下游系统 4. **数据库**: - 数据库配置已移至 `.env` 文件中 - 使用 MySQL 数据库 - 确保 MySQL 服务已启动并创建了相应的数据库 - 定期清理过期的 SSO Token ## 下游系统集成示例 ### JavaScript/TypeScript 示例 ```javascript // 1. 检查是否已登录 async function checkAuth() { const token = localStorage.getItem('sso_token'); if (!token) { // 重定向到 SSO 系统 window.location.href = 'http://sso-system.com/api/auth/sso/callback/?token=' + getSSOToken(); return; } // 2. 验证 Token const response = await fetch('http://sso-system.com/api/auth/sso/verify/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ token }), }); const data = await response.json(); if (data.valid) { // 用户已认证,创建本地会话 createLocalSession(data.user); } else { // Token 无效,重新登录 redirectToSSO(); } } // 3. 从 URL 参数获取 Token(回调时) function handleCallback() { const urlParams = new URLSearchParams(window.location.search); const token = urlParams.get('token'); if (token) { localStorage.setItem('sso_token', token); // 清除 URL 中的 token 参数 window.history.replaceState({}, document.title, window.location.pathname); } } ``` ## 开发说明 ### 项目结构 ``` login/ ├── manage.py ├── requirements.txt ├── sso_project/ # Django 项目配置 │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── sso_auth/ # SSO 认证应用 │ ├── models.py # 用户模型和 SSO Token 模型 │ ├── views.py # API 视图 │ ├── serializers.py # 序列化器 │ ├── utils.py # JWT 和 SSO Token 工具函数 │ ├── authentication.py # JWT 认证类 │ ├── backends.py # 手机号认证后端 │ └── urls.py # URL 路由 └── README.md ``` ## 许可证 MIT License