Fix Casdoor login URL issue and enhance user experience. Updated organization name in environment variables, improved error handling for login failures, and added automatic redirection to Casdoor login page. Enhanced user interface with new styles for user display in the navigation bar. Updated logging to capture detailed user actions and application events.

This commit is contained in:
2025-12-11 22:24:20 +08:00
parent 539a981567
commit 2d5c5d4c0d
15 changed files with 2189 additions and 523 deletions
+454
View File
@@ -0,0 +1,454 @@
# Casdoor 集成经验总结
本文档总结了在 Flask 项目中集成 Casdoor 并使用现有登录页面时遇到的所有问题和解决方案,帮助后续项目避免踩坑。
## 目录
1. [集成方式选择](#集成方式选择)
2. [配置步骤](#配置步骤)
3. [常见问题与解决方案](#常见问题与解决方案)
4. [最佳实践](#最佳实践)
5. [代码示例](#代码示例)
---
## 集成方式选择
### 方式一:OAuth 重定向方式(不推荐用于现有登录页面)
**特点:**
- 用户点击登录后跳转到 Casdoor 登录页面
- 登录成功后回调到项目
- 适合新项目或不需要保留现有登录页面的场景
**缺点:**
- 无法使用项目现有的登录页面
- 用户体验不够统一
### 方式二:API 方式(推荐)
**特点:**
- 使用 OAuth 2.0 password grant 方式
- 在项目现有登录页面输入用户名密码
- 通过 API 直接验证,无需跳转
- 用户体验更好,界面统一
**推荐使用方式二**
---
## 配置步骤
### 1. 环境变量配置
`.env` 文件或系统环境变量中添加:
```bash
# Casdoor 服务地址
CASDOOR_ENDPOINT=https://your-casdoor-server.com
# Casdoor 应用配置(在 Casdoor 管理界面创建应用后获取)
CASDOOR_CLIENT_ID=your_client_id
CASDOOR_CLIENT_SECRET=your_client_secret
# 组织名称和应用名称(通常在 Casdoor 中配置)
CASDOOR_ORGANIZATION_NAME=your_organization
CASDOOR_APPLICATION_NAME=your_application
# 会话 Cookie 配置(跨域 SSO 时建议设置)
SESSION_COOKIE_SAMESITE=Lax # 或 None(跨域时)
SESSION_COOKIE_SECURE=False # HTTPS 时设为 True
```
### 2. 在 Casdoor 中创建应用
1. 登录 Casdoor 管理界面
2. 进入 "Applications" 页面
3. 创建新应用,记录 `Client ID``Client Secret`
4. **重要**:确保应用启用了 password grant 方式(如果 Casdoor 版本支持)
### 3. 代码集成
参考项目中的以下文件:
- `app/utils/casdoor_auth.py` - Casdoor 认证工具类
- `app/views/auth.py` - 认证路由处理
- `app/templates/login.html` - 登录页面模板
---
## 常见问题与解决方案
### 问题 1:登录后提示 "Please log in to access this page"
**原因:**
- Flask-Login 的默认提示消息是英文
- 登录成功后可能有残留的 flash 消息
**解决方案:**
`app.py` 中配置 Flask-Login
```python
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.login_message = '请先登录以访问此页面' # 设置中文提示
login_manager.login_message_category = 'info'
```
在登录成功后清除 flash 消息:
```python
# 在 auth.py 的登录成功处理中
session.pop('_flashes', None)
```
在模板中过滤已登录用户的未登录提示:
```html
<!-- base.html -->
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
{% if not (current_user.is_authenticated and '请先登录' in message) %}
<!-- 显示消息 -->
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
```
### 问题 2API 登录返回 "Unauthorized operation"
**原因:**
- 使用了错误的 API 端点
- 参数格式不正确
- 未使用 OAuth 2.0 password grant 方式
**解决方案:**
使用正确的 OAuth 2.0 password grant 端点:
```python
login_url = f"{endpoint}/api/login/oauth/access_token"
data = {
'grant_type': 'password', # 必须指定 grant_type
'username': username,
'password': password,
'client_id': client_id, # 必须包含 client_id
'client_secret': client_secret, # 必须包含 client_secret
'scope': 'openid profile email phone'
}
```
**注意:** 某些 Casdoor 版本可能不支持 password grant,需要检查 Casdoor 文档或使用 OAuth 授权码方式。
### 问题 3:退出时跳转到 Casdoor 404 页面
**原因:**
- 退出时尝试跳转到 Casdoor 的退出页面
- Casdoor 退出 URL 不正确
**解决方案:**
如果不需要同时退出 Casdoor,只退出本地会话:
```python
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
```
如果需要同时退出 Casdoor,使用正确的退出 URL
```python
# 注意:需要确保 redirect_uri 在 Casdoor 应用的回调白名单中
logout_url = f"{casdoor_endpoint}/login/oauth/logout?client_id={client_id}&redirect_uri={login_url}"
```
### 问题 4:语法错误 - try-except 块不匹配
**原因:**
- 代码重构时 try 块未正确闭合
- 在 try 块外使用了 try 块内定义的变量
**解决方案:**
确保所有逻辑都在完整的 try-except 块中:
```python
try:
# 所有逻辑代码
response = requests.post(...)
result = response.json()
# ... 处理逻辑
return result
except requests.exceptions.Timeout:
# 处理超时
return None
except requests.exceptions.RequestException as e:
# 处理请求异常
return None
except Exception as e:
# 处理其他异常
return None
```
**检查要点:**
- 每个 `try` 必须有对应的 `except``finally`
- 变量作用域要正确(在 try 块内定义的变量不能在块外使用)
### 问题 5:API 响应格式解析错误
**原因:**
- Casdoor API 返回格式可能不同
- 未处理各种可能的响应格式
**解决方案:**
兼容多种响应格式:
```python
result = response.json()
# 检查错误
if isinstance(result, dict) and result.get('status') == 'error':
error_msg = result.get('msg', '未知错误')
return None
# 尝试多种格式获取 token
access_token = None
if isinstance(result, dict):
# 标准 OAuth 2.0 格式
access_token = result.get('access_token')
# Casdoor 格式 {"status": "ok", "data": {...}}
if not access_token and result.get('status') == 'ok':
token_data = result.get('data', {})
if isinstance(token_data, dict):
access_token = token_data.get('access_token')
# 其他可能的字段
if not access_token:
access_token = result.get('token') or result.get('accessToken')
```
### 问题 6:用户信息同步问题
**原因:**
- Casdoor 返回的用户信息字段名可能不同
- 本地数据库字段映射不正确
**解决方案:**
使用多个可能的字段名:
```python
# 从 Casdoor 用户信息中提取数据
casdoor_id = user_info.get('sub') or user_info.get('id') or user_info.get('name')
phone = user_info.get('phone') or user_info.get('phoneNumber') or casdoor_id
name = user_info.get('name') or user_info.get('displayName') or username
branch = user_info.get('affiliation', '')
role = user_info.get('type', '')
```
### 问题 7:会话 Cookie 配置问题
**原因:**
- 跨域时 Cookie 无法正确设置
- SameSite 和 Secure 属性配置不当
**解决方案:**
`config.py` 中配置:
```python
# 跨域 SSO 时
SESSION_COOKIE_SAMESITE = 'None' # 需要配合 Secure=True
SESSION_COOKIE_SECURE = True # HTTPS 必须
# 同域时
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_SECURE = False # HTTP 开发环境
```
**注意:** `SameSite=None` 必须配合 `Secure=True` 使用,且需要 HTTPS。
---
## 最佳实践
### 1. 错误处理
- 始终使用 try-except 包裹 API 调用
- 记录详细的错误日志,便于排查
- 对用户显示友好的错误提示
```python
try:
result = casdoor_auth.login_with_password(username, password)
if not result:
flash('用户名或密码错误')
return render_template('login.html')
except Exception as e:
app.logger.error(f"登录异常: {str(e)}")
flash('登录失败,请稍后重试')
return render_template('login.html')
```
### 2. 日志记录
- 记录登录尝试(不记录密码)
- 记录 API 调用结果
- 记录用户信息同步情况
```python
app.logger.info(f"尝试 Casdoor API 登录: username={username}")
app.logger.info(f"Casdoor 用户信息: {user_info}")
app.logger.info(f"用户 {user.name}({user.phone}) 通过 Casdoor API 登录成功")
```
### 3. 安全性
- 永远不要在日志中记录密码
- 使用 HTTPS(生产环境)
- 验证和清理用户输入
- 使用环境变量存储敏感配置
### 4. 用户体验
- 提供清晰的错误提示
- 登录成功后清除残留的提示消息
- 保持登录页面的原有样式
### 5. 代码组织
- 将 Casdoor 相关逻辑封装在独立的工具类中
- 保持路由处理简洁
- 使用配置类管理所有配置项
---
## 代码示例
### 完整的认证工具类结构
```python
# app/utils/casdoor_auth.py
class CasdoorAuth:
def __init__(self, app=None):
self.app = app
if app:
self.init_app(app)
def init_app(self, app):
"""初始化应用配置"""
self.endpoint = app.config.get('CASDOOR_ENDPOINT')
self.client_id = app.config.get('CASDOOR_CLIENT_ID')
self.client_secret = app.config.get('CASDOOR_CLIENT_SECRET')
self.organization_name = app.config.get('CASDOOR_ORGANIZATION_NAME', 'built-in')
self.application_name = app.config.get('CASDOOR_APPLICATION_NAME', 'app-built-in')
def login_with_password(self, username, password):
"""使用用户名和密码通过 API 登录"""
login_url = f"{self.endpoint}/api/login/oauth/access_token"
data = {
'grant_type': 'password',
'username': username,
'password': password,
'client_id': self.client_id,
'client_secret': self.client_secret,
'scope': 'openid profile email phone'
}
try:
response = requests.post(login_url, data=data, timeout=10)
# ... 处理响应
except Exception as e:
# ... 错误处理
return None
def get_user_info(self, access_token):
"""使用访问令牌获取用户信息"""
# ... 实现
pass
```
### 登录路由处理
```python
# app/views/auth.py
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('dashboard'))
if request.method == 'POST':
username = request.form.get('username', '').strip()
password = request.form.get('password', '').strip()
if not username or not password:
flash('请输入用户名和密码')
return render_template('login.html')
# 使用 API 方式登录
result = casdoor_auth.login_with_password(username, password)
if not result:
flash('用户名或密码错误')
return render_template('login.html')
# 处理用户信息同步
user_info = result.get('user_info', {})
# ... 创建或更新用户
login_user(user)
session.pop('_flashes', None) # 清除残留提示
return redirect(url_for('dashboard'))
return render_template('login.html')
```
---
## 检查清单
在集成 Casdoor 时,确保完成以下检查:
- [ ] 环境变量配置正确
- [ ] Casdoor 应用已创建并获取 Client ID 和 Secret
- [ ] 使用正确的 API 端点(`/api/login/oauth/access_token`
- [ ] 使用 OAuth 2.0 password grant 方式
- [ ] 所有 try-except 块正确闭合
- [ ] 错误处理完善,有详细的日志记录
- [ ] 登录成功后清除残留的 flash 消息
- [ ] 用户信息同步逻辑正确
- [ ] 会话 Cookie 配置正确(跨域时)
- [ ] 登录页面样式保持一致
- [ ] 测试各种错误场景(错误密码、网络错误等)
---
## 参考资源
- [Casdoor 官方文档](https://casdoor.org/docs/overview)
- [OAuth 2.0 Password Grant](https://oauth.net/2/grant-types/password/)
- [Flask-Login 文档](https://flask-login.readthedocs.io/)
---
## 总结
集成 Casdoor 到现有项目时,主要注意以下几点:
1. **选择正确的集成方式**API 方式更适合保留现有登录页面
2. **使用正确的 API 端点和参数**OAuth 2.0 password grant 方式
3. **完善的错误处理**:处理各种异常情况和响应格式
4. **用户体验优化**:清除残留提示,保持界面统一
5. **安全性考虑**:使用 HTTPS,不在日志中记录敏感信息
遵循以上实践,可以避免大部分常见问题,顺利完成 Casdoor 集成。
+1 -1
View File
@@ -40,5 +40,5 @@ CASDOOR_ENDPOINT=https://casdoor.dhdx.fun
CASDOOR_CLIENT_ID=8f323670e073612794ef
CASDOOR_CLIENT_SECRET=bc37d89f9220fe5a46c17125c731d2daf22f1299
CASDOOR_REDIRECT_URI=https://zd.dhdx.fun/callback
CASDOOR_ORGANIZATION_NAME=built-in
CASDOOR_ORGANIZATION_NAME=dahua
CASDOOR_APPLICATION_NAME=4an
Binary file not shown.
Binary file not shown.
+98 -98
View File
@@ -1,99 +1,99 @@
from flask import Flask, redirect, url_for
from flask_login import LoginManager
from flask_migrate import Migrate
from scripts.models import db, User, Device, WorkOrder, WorkOrderHandling, ManualWorkOrder
from config import Config
from views.auth import init_auth_routes
from views.work_order import init_work_order_routes
from views.statistics import init_statistics_routes
from views.history import init_history_routes
from views.manual import init_manual_routes
from views.device import init_device_routes
from views.about import init_about_routes
from views.dashboard import init_dashboard_routes
from views.user import init_user_routes
import logging
from logging.handlers import RotatingFileHandler
import os
from utils.error_handlers import ErrorHandler
def create_app():
# 创建应用实例
app = Flask(__name__)
app.config.from_object(Config)
# 配置日志记录
if not os.path.exists('logs'):
os.makedirs('logs')
# 创建日志处理器,设置最大文件大小为10MB,保留5个备份文件
file_handler = RotatingFileHandler(
'logs/app.log',
maxBytes=10*1024*1024, # 10MB
backupCount=5,
encoding='utf-8'
)
# 设置日志格式
formatter = logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s',
'%Y-%m-%d %H:%M:%S'
)
file_handler.setFormatter(formatter)
# 设置日志级别
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('应用启动')
# 初始化数据库
db.init_app(app)
migrate = Migrate(app, db)
# 初始化异常处理器
error_handler = ErrorHandler(app)
# 初始化登录管理器
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# 默认未登录提示改为中文
login_manager.login_message = '请先登录以访问此页面'
@login_manager.user_loader
def load_user(user_id):
try:
return db.session.get(User, user_id)
except Exception as e:
app.logger.error(f"加载用户时出错: {str(e)}")
return None
# 注册路由
@app.route('/')
def index():
return redirect(url_for('dashboard'))
# 初始化各模块路由
init_auth_routes(app)
init_work_order_routes(app)
init_statistics_routes(app)
init_history_routes(app)
init_manual_routes(app)
init_device_routes(app)
init_about_routes(app)
init_dashboard_routes(app)
init_user_routes(app)
return app
app = create_app()
if __name__ == '__main__':
with app.app_context():
try:
db.create_all()
app.logger.info("数据库表创建成功")
except Exception as e:
app.logger.error(f"创建数据库表时出错: {str(e)}")
from flask import Flask, redirect, url_for
from flask_login import LoginManager
from flask_migrate import Migrate
from scripts.models import db, User, Device, WorkOrder, WorkOrderHandling, ManualWorkOrder
from config import Config
from views.auth import init_auth_routes
from views.work_order import init_work_order_routes
from views.statistics import init_statistics_routes
from views.history import init_history_routes
from views.manual import init_manual_routes
from views.device import init_device_routes
from views.about import init_about_routes
from views.dashboard import init_dashboard_routes
from views.user import init_user_routes
import logging
from logging.handlers import RotatingFileHandler
import os
from utils.error_handlers import ErrorHandler
def create_app():
# 创建应用实例
app = Flask(__name__)
app.config.from_object(Config)
# 配置日志记录
if not os.path.exists('logs'):
os.makedirs('logs')
# 创建日志处理器,设置最大文件大小为10MB,保留5个备份文件
file_handler = RotatingFileHandler(
'logs/app.log',
maxBytes=10*1024*1024, # 10MB
backupCount=5,
encoding='utf-8'
)
# 设置日志格式
formatter = logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s',
'%Y-%m-%d %H:%M:%S'
)
file_handler.setFormatter(formatter)
# 设置日志级别
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('应用启动')
# 初始化数据库
db.init_app(app)
migrate = Migrate(app, db)
# 初始化异常处理器
error_handler = ErrorHandler(app)
# 初始化登录管理器
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# 默认未登录提示改为中文
login_manager.login_message = '请先登录以访问此页面'
@login_manager.user_loader
def load_user(user_id):
try:
return db.session.get(User, user_id)
except Exception as e:
app.logger.error(f"加载用户时出错: {str(e)}")
return None
# 注册路由
@app.route('/')
def index():
return redirect(url_for('dashboard'))
# 初始化各模块路由
init_auth_routes(app)
init_work_order_routes(app)
init_statistics_routes(app)
init_history_routes(app)
init_manual_routes(app)
init_device_routes(app)
init_about_routes(app)
init_dashboard_routes(app)
init_user_routes(app)
return app
app = create_app()
if __name__ == '__main__':
with app.app_context():
try:
db.create_all()
app.logger.info("数据库表创建成功")
except Exception as e:
app.logger.error(f"创建数据库表时出错: {str(e)}")
app.run(host='0.0.0.0', port=18019, debug=True)
+1101 -40
View File
File diff suppressed because it is too large Load Diff
+9
View File
@@ -93,6 +93,15 @@
color: white !important;
}
.nav_user_name {
color: rgba(255,255,255,0.9) !important;
padding: 0.5rem 1rem !important;
font-weight: 500;
display: block;
cursor: default;
pointer-events: none;
}
/* 接单平台样式 */
.receive_container {
padding: 20px;
+3
View File
@@ -84,6 +84,9 @@
</ul>
<ul class="navbar-nav nav_menu">
{% if current_user.is_authenticated %}
<li class="nav-item">
<span class="nav_link nav_user_name">{{ current_user.name }}</span>
</li>
<li class="nav-item">
<a class="nav_link" href="{{ url_for('logout') }}">退出</a>
</li>
+25 -18
View File
@@ -5,25 +5,32 @@
<h2 class="login_title">欢迎使用</h2>
<div class="login_subtitle">大化重点项目工单管理平台</div>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="login_error">
{% for message in messages %}
{{ message }}
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="login_error">
{% for message in messages %}
{{ message }}
{% endfor %}
</div>
{% endif %}
{% endwith %}
<!-- Casdoor 登录按钮 -->
<div class="login_casdoor_section">
<a href="{{ url_for('casdoor_login') }}" class="login_button login_button_casdoor">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 8px;">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="currentColor"/>
</svg>
使用 Casdoor 登录
</a>
</div>
<!-- Casdoor 登录跳转 -->
<div class="login_casdoor_section">
<a href="{{ url_for('casdoor_login') }}" class="login_button login_button_casdoor">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 8px;">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="currentColor"/>
</svg>
使用 Casdoor 登录
</a>
<p style="margin-top: 12px; color: #666;">正在跳转至 Casdoor 登录页,如未跳转请点击按钮。</p>
</div>
<script>
// 自动跳转至 Casdoor 登录
window.onload = function() {
window.location.href = "{{ url_for('casdoor_login') }}";
};
</script>
</div>
</div>
{% endblock %}
Binary file not shown.
+130
View File
@@ -123,6 +123,136 @@ class CasdoorAuth:
session.pop('casdoor_state', None)
return True
return False
def login_with_password(self, username, password):
"""
使用用户名和密码通过 API 登录 Casdoor
Args:
username: 用户名
password: 密码
Returns:
dict: 包含 access_token 和用户信息的字典,失败返回 None
"""
# Casdoor 使用 OAuth 2.0 password grant 方式登录
# 端点应该是 /api/login/oauth/access_token
login_url = f"{self.endpoint}/api/login/oauth/access_token"
# OAuth 2.0 password grant 需要的参数
data = {
'grant_type': 'password',
'username': username,
'password': password,
'client_id': self.client_id,
'client_secret': self.client_secret,
'scope': 'openid profile email phone'
}
try:
current_app.logger.info(f"尝试 Casdoor OAuth password grant 登录: username={username}")
except:
pass
try:
# OAuth 2.0 password grant 通常使用 form-data 格式
response = requests.post(login_url, data=data, timeout=10)
# 如果返回 415,尝试 JSON 格式
if response.status_code == 415:
response = requests.post(login_url, json=data, timeout=10)
# 检查响应状态
if response.status_code != 200:
try:
error_msg = response.text[:200] # 限制错误消息长度
current_app.logger.warning(f"Casdoor OAuth 登录失败 (状态码 {response.status_code}): {error_msg}")
except:
pass
return None
# 尝试解析 JSON 响应
try:
result = response.json()
except ValueError as e:
try:
current_app.logger.error(f"Casdoor API 登录响应不是有效的 JSON: {str(e)}, 响应内容: {response.text[:200]}")
except:
pass
return None
# 检查 result 是否为 None
if result is None:
try:
current_app.logger.error("Casdoor API 登录返回 None")
except:
pass
return None
# OAuth 2.0 返回格式通常是 {"access_token": "...", "token_type": "Bearer", ...}
# 或者 Casdoor 格式 {"status": "ok", "data": {"access_token": "..."}}
access_token = None
if isinstance(result, dict):
# 检查是否有错误
if result.get('status') == 'error':
try:
error_msg = result.get('msg', '未知错误')
current_app.logger.warning(f"Casdoor OAuth 登录错误: {error_msg}")
except:
pass
return None
# 标准 OAuth 2.0 格式
access_token = result.get('access_token')
# Casdoor 格式 {"status": "ok", "data": {...}}
if not access_token and result.get('status') == 'ok':
token_data = result.get('data', {})
if isinstance(token_data, dict):
access_token = token_data.get('access_token') or token_data.get('token') or token_data.get('accessToken')
# 如果还是没有,尝试其他可能的字段
if not access_token:
access_token = result.get('token') or result.get('accessToken')
# 如果还是没有 token,尝试从其他字段获取
if not access_token and 'data' in result and isinstance(result.get('data'), dict):
access_token = result['data'].get('access_token') or result['data'].get('token')
if not access_token:
try:
current_app.logger.warning(f"Casdoor API 登录返回格式异常,未找到 token: {result}")
except:
pass
return None
# 使用 token 获取用户信息
user_info = self.get_user_info(access_token)
if not user_info:
return None
return {
'access_token': access_token,
'user_info': user_info
}
except requests.exceptions.Timeout:
try:
current_app.logger.error("Casdoor API 登录超时")
except:
pass
return None
except requests.exceptions.RequestException as e:
try:
current_app.logger.error(f"Casdoor API 登录失败: {str(e)}")
except:
pass
return None
except Exception as e:
try:
current_app.logger.error(f"Casdoor API 登录发生未知错误: {str(e)}")
except:
pass
return None
# 创建全局实例
Binary file not shown.
+112 -112
View File
@@ -1,113 +1,113 @@
from flask import render_template, request, redirect, url_for, flash, session
import urllib.parse
from flask_login import login_user, login_required, logout_user, current_user
from scripts.models import db, User
from utils.casdoor_auth import casdoor_auth
def init_auth_routes(app):
# 初始化 Casdoor 认证
casdoor_auth.init_app(app)
@app.route('/login', methods=['GET', 'POST'])
def login():
# 已登录直接进入仪表盘,否则跳转 Casdoor 登录
if current_user.is_authenticated:
return redirect(url_for('dashboard'))
return redirect(url_for('casdoor_login'))
@app.route('/casdoor/login')
def casdoor_login():
"""Casdoor 登录入口,重定向到 Casdoor 授权页面"""
if not app.config.get('CASDOOR_CLIENT_ID'):
flash('Casdoor 未配置,请使用手机号登录')
return redirect(url_for('login'))
auth_url = casdoor_auth.get_authorization_url()
app.logger.info('重定向到 Casdoor 授权页面')
return redirect(auth_url)
@app.route('/callback')
def casdoor_callback():
"""Casdoor OAuth 回调处理"""
code = request.args.get('code')
state = request.args.get('state')
error = request.args.get('error')
if error:
app.logger.error(f'Casdoor 认证失败: {error}')
flash(f'登录失败: {error}')
return redirect(url_for('login'))
if not code:
app.logger.warning('Casdoor 回调缺少授权码')
flash('登录失败:未收到授权码')
return redirect(url_for('login'))
# 验证 state 参数
if not casdoor_auth.verify_state(state):
app.logger.warning('Casdoor state 验证失败,可能存在 CSRF 攻击')
flash('登录失败:安全验证失败')
return redirect(url_for('login'))
# 获取访问令牌
token_data = casdoor_auth.get_token(code)
if not token_data or 'access_token' not in token_data:
app.logger.error('获取 Casdoor token 失败')
flash('登录失败:无法获取访问令牌')
return redirect(url_for('login'))
access_token = token_data['access_token']
# 获取用户信息
user_info = casdoor_auth.get_user_info(access_token)
if not user_info:
app.logger.error('获取 Casdoor 用户信息失败')
flash('登录失败:无法获取用户信息')
return redirect(url_for('login'))
# 从 Casdoor 用户信息中提取数据
# Casdoor 返回的用户信息可能包含:name, email, phone, id 等字段
casdoor_id = user_info.get('sub') or user_info.get('id') or user_info.get('name')
phone = user_info.get('phone') or user_info.get('phoneNumber') or casdoor_id
name = user_info.get('name') or user_info.get('displayName') or '未知用户'
app.logger.info(f'Casdoor 用户信息: {user_info}')
# 查找或创建本地用户
user = User.query.filter_by(phone=phone).first()
if not user:
# 如果用户不存在,创建新用户
user = User(
phone=phone,
name=name,
branch=user_info.get('affiliation', ''),
role=user_info.get('type', '')
)
db.session.add(user)
db.session.commit()
app.logger.info(f'创建新用户: {name}({phone})')
else:
# 更新用户信息
user.name = name
if user_info.get('affiliation'):
user.branch = user_info.get('affiliation')
if user_info.get('type'):
user.role = user_info.get('type')
db.session.commit()
app.logger.info(f'更新用户信息: {name}({phone})')
# 登录用户
login_user(user)
app.logger.info(f'用户 {user.name}({user.phone}) 通过 Casdoor 登录成功')
# 清除可能残留的未登录提示
session.pop('_flashes', None)
return redirect(url_for('dashboard'))
@app.route('/logout')
@login_required
def logout():
app.logger.info(f'用户 {current_user.name}({current_user.phone}) 登出')
logout_user()
# 仅退出本地会话,保留 Casdoor 登录态
from flask import render_template, request, redirect, url_for, flash, session
import urllib.parse
from flask_login import login_user, login_required, logout_user, current_user
from scripts.models import db, User
from utils.casdoor_auth import casdoor_auth
def init_auth_routes(app):
# 初始化 Casdoor 认证
casdoor_auth.init_app(app)
@app.route('/login', methods=['GET', 'POST'])
def login():
# 如果已登录直接跳转到仪表盘
if current_user.is_authenticated:
return redirect(url_for('dashboard'))
# 未登录直接跳转 Casdoor 登录页
return redirect(url_for('casdoor_login'))
@app.route('/casdoor/login')
def casdoor_login():
"""重定向到 Casdoor 登录页面"""
if not app.config.get('CASDOOR_CLIENT_ID'):
flash('Casdoor 未配置,无法登录')
return redirect(url_for('login'))
auth_url = casdoor_auth.get_authorization_url()
app.logger.info('重定向到 Casdoor 授权页面')
return redirect(auth_url)
@app.route('/callback')
def casdoor_callback():
"""Casdoor OAuth 回调处理"""
code = request.args.get('code')
state = request.args.get('state')
error = request.args.get('error')
if error:
app.logger.error(f'Casdoor 认证失败: {error}')
flash(f'登录失败: {error}')
return redirect(url_for('login'))
if not code:
app.logger.warning('Casdoor 回调缺少授权码')
flash('登录失败:未收到授权码')
return redirect(url_for('login'))
# 验证 state 参数
if not casdoor_auth.verify_state(state):
app.logger.warning('Casdoor state 验证失败,可能存在 CSRF 攻击')
flash('登录失败:安全验证失败')
return redirect(url_for('login'))
# 获取访问令牌
token_data = casdoor_auth.get_token(code)
if not token_data or 'access_token' not in token_data:
app.logger.error('获取 Casdoor token 失败')
flash('登录失败:无法获取访问令牌')
return redirect(url_for('login'))
access_token = token_data['access_token']
# 获取用户信息
user_info = casdoor_auth.get_user_info(access_token)
if not user_info:
app.logger.error('获取 Casdoor 用户信息失败')
flash('登录失败:无法获取用户信息')
return redirect(url_for('login'))
# 从 Casdoor 用户信息中提取数据
# Casdoor 返回的用户信息可能包含:name, email, phone, id 等字段
casdoor_id = user_info.get('sub') or user_info.get('id') or user_info.get('name')
phone = user_info.get('phone') or user_info.get('phoneNumber') or casdoor_id
name = user_info.get('name') or user_info.get('displayName') or '未知用户'
app.logger.info(f'Casdoor 用户信息: {user_info}')
# 查找或创建本地用户
user = User.query.filter_by(phone=phone).first()
if not user:
# 如果用户不存在,创建新用户
user = User(
phone=phone,
name=name,
branch=user_info.get('affiliation', ''),
role=user_info.get('type', '')
)
db.session.add(user)
db.session.commit()
app.logger.info(f'创建新用户: {name}({phone})')
else:
# 更新用户信息
user.name = name
if user_info.get('affiliation'):
user.branch = user_info.get('affiliation')
if user_info.get('type'):
user.role = user_info.get('type')
db.session.commit()
app.logger.info(f'更新用户信息: {name}({phone})')
# 登录用户
login_user(user)
app.logger.info(f'用户 {user.name}({user.phone}) 通过 Casdoor 登录成功')
# 清除可能残留的未登录提示
session.pop('_flashes', None)
return redirect(url_for('dashboard'))
@app.route('/logout')
@login_required
def logout():
app.logger.info(f'用户 {current_user.name}({current_user.phone}) 登出')
logout_user()
# 仅退出本地会话,保留 Casdoor 登录态
return redirect(url_for('login'))
+255 -253
View File
@@ -1,13 +1,229 @@
[2025-12-11 22:21:50,347] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:51,162] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:53,765] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:55,427] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:56,245] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:57,458] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:58,265] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:21:59,973] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[2025-12-11 22:22:01,191] ERROR in error_handlers: 未处理异常: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
Traceback (most recent call last):
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/4an/app/views/auth.py", line 17, in login
return redirect(url_for('casdoor_login'))
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/helpers.py", line 239, in url_for
return current_app.url_for(
^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1121, in url_for
return self.handle_url_build_error(error, endpoint, values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/flask/app.py", line 1110, in url_for
rv = url_adapter.build( # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/v6ole/pyproject/venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 924, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'casdoor_login'. Did you mean 'casdoor_callback' instead?
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
gateway "uWSGI http 1" has been buried (pid: 1742819)
gateway "uWSGI http 1" has been buried (pid: 2840701)
...gracefully killing workers...
Gracefully killing worker 1 (pid: 1742806)...
Gracefully killing worker 4 (pid: 1742815)...
Gracefully killing worker 3 (pid: 1742810)...
Gracefully killing worker 2 (pid: 1742809)...
Gracefully killing worker 1 (pid: 2840688)...
Gracefully killing worker 3 (pid: 2840692)...
Gracefully killing worker 4 (pid: 2840695)...
Gracefully killing worker 2 (pid: 2840691)...
worker 1 buried after 1 seconds
worker 2 buried after 1 seconds
worker 3 buried after 1 seconds
@@ -18,7 +234,7 @@ closing all non-uwsgi socket fds > 2 (max_fd = 1024)...
found fd 9 mapped to socket 0 (/home/v6ole/pyproject/4an/uwsgi.sock)
running /home/v6ole/pyproject/venv/bin/uwsgi
[uWSGI] getting INI configuration from /home/v6ole/pyproject/4an/app/uwsgi.ini
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:31:51 2025] ***
*** Starting uWSGI 2.0.31 (64bit) on [Thu Dec 11 22:23:17 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
@@ -41,7 +257,7 @@ uWSGI http bound on 0.0.0.0:18019 fd 7
probably another instance of uWSGI is running on the same address (0.0.0.0:18019).
bind(): Address already in use [core/socket.c line 769]
VACUUM: pidfile removed.
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:31:53 2025] ***
*** Starting uWSGI 2.0.31 (64bit) on [Thu Dec 11 22:23:18 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
@@ -68,7 +284,7 @@ uWSGI running as root, you can use --uid/--gid/--chroot options
Python version: 3.12.3 (main, Nov 6 2025, 13:44:16) [GCC 13.3.0]
PEP 405 virtualenv detected: /home/v6ole/pyproject/venv
Set PythonHome to /home/v6ole/pyproject/venv
Python main interpreter initialized at 0x71c06d2a3668
Python main interpreter initialized at 0x78df1aea3668
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
python threads support enabled
@@ -76,32 +292,31 @@ your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 703440 bytes (686 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
[2025-12-10 16:31:53,941] INFO in app: 应用启动
[2025-12-10 16:31:53,943] INFO in error_handlers: 错误处理器初始化完成
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x71c06d2a3668 pid: 1746324 (default app)
[2025-12-11 22:23:19,123] INFO in app: 应用启动
[2025-12-11 22:23:19,124] INFO in error_handlers: 错误处理器初始化完成
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x78df1aea3668 pid: 2854900 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1746324)
spawned uWSGI worker 1 (pid: 1746507, cores: 2)
spawned uWSGI worker 2 (pid: 1746510, cores: 2)
spawned uWSGI master process (pid: 2854900)
spawned uWSGI worker 1 (pid: 2855094, cores: 2)
Python auto-reloader enabled
spawned uWSGI worker 3 (pid: 1746513, cores: 2)
spawned uWSGI worker 4 (pid: 1746516, cores: 2)
spawned uWSGI worker 2 (pid: 2855098, cores: 2)
spawned uWSGI worker 3 (pid: 2855101, cores: 2)
spawned uWSGI worker 4 (pid: 2855102, cores: 2)
*** Stats server enabled on 127.0.0.1:9191 fd: 22 ***
spawned uWSGI http 1 (pid: 1746518)
spawned uWSGI http 1 (pid: 2855106)
unable to stat() uwsgi.reload, events will be triggered as soon as the file is created
unable to stat() true, events will be triggered as soon as the file is created
[2025-12-11 22:23:29,628] INFO in auth: 重定向到 Casdoor 授权页面
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
gateway "uWSGI http 1" has been buried (pid: 1746518)
gateway "uWSGI http 1" has been buried (pid: 2855106)
...gracefully killing workers...
Gracefully killing worker 1 (pid: 1746507)...
Gracefully killing worker 4 (pid: 1746516)...
Gracefully killing worker 3 (pid: 1746513)...
Gracefully killing worker 2 (pid: 1746510)...
Gracefully killing worker 2 (pid: 2855098)...
Gracefully killing worker 3 (pid: 2855101)...
Gracefully killing worker 4 (pid: 2855102)...
Gracefully killing worker 1 (pid: 2855094)...
worker 1 buried after 1 seconds
worker 2 buried after 1 seconds
worker 3 buried after 1 seconds
@@ -112,7 +327,7 @@ closing all non-uwsgi socket fds > 2 (max_fd = 1024)...
found fd 9 mapped to socket 0 (/home/v6ole/pyproject/4an/uwsgi.sock)
running /home/v6ole/pyproject/venv/bin/uwsgi
[uWSGI] getting INI configuration from /home/v6ole/pyproject/4an/app/uwsgi.ini
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:32:43 2025] ***
*** Starting uWSGI 2.0.31 (64bit) on [Thu Dec 11 22:23:36 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
@@ -135,7 +350,7 @@ uWSGI http bound on 0.0.0.0:18019 fd 7
probably another instance of uWSGI is running on the same address (0.0.0.0:18019).
bind(): Address already in use [core/socket.c line 769]
VACUUM: pidfile removed.
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:32:44 2025] ***
*** Starting uWSGI 2.0.31 (64bit) on [Thu Dec 11 22:23:37 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
@@ -162,7 +377,7 @@ uWSGI running as root, you can use --uid/--gid/--chroot options
Python version: 3.12.3 (main, Nov 6 2025, 13:44:16) [GCC 13.3.0]
PEP 405 virtualenv detected: /home/v6ole/pyproject/venv
Set PythonHome to /home/v6ole/pyproject/venv
Python main interpreter initialized at 0x7410a7ea3668
Python main interpreter initialized at 0x7121faaa3668
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
python threads support enabled
@@ -170,236 +385,23 @@ your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 703440 bytes (686 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
[2025-12-10 16:32:45,024] INFO in app: 应用启动
[2025-12-10 16:32:45,026] INFO in error_handlers: 错误处理器初始化完成
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7410a7ea3668 pid: 1747945 (default app)
[2025-12-11 22:23:38,073] INFO in app: 应用启动
[2025-12-11 22:23:38,074] INFO in error_handlers: 错误处理器初始化完成
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7121faaa3668 pid: 2857150 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1747945)
spawned uWSGI worker 1 (pid: 1748124, cores: 2)
spawned uWSGI master process (pid: 2857150)
spawned uWSGI worker 1 (pid: 2857296, cores: 2)
spawned uWSGI worker 2 (pid: 2857300, cores: 2)
Python auto-reloader enabled
spawned uWSGI worker 2 (pid: 1748127, cores: 2)
spawned uWSGI worker 3 (pid: 1748128, cores: 2)
spawned uWSGI worker 4 (pid: 1748130, cores: 2)
spawned uWSGI worker 3 (pid: 2857303, cores: 2)
spawned uWSGI worker 4 (pid: 2857304, cores: 2)
*** Stats server enabled on 127.0.0.1:9191 fd: 22 ***
spawned uWSGI http 1 (pid: 1748137)
spawned uWSGI http 1 (pid: 2857309)
unable to stat() uwsgi.reload, events will be triggered as soon as the file is created
unable to stat() true, events will be triggered as soon as the file is created
[2025-12-10 16:36:04,465] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-10 16:36:13,335] INFO in auth: Casdoor 用户信息: {'sub': '798f4436-fbb6-45f4-bf0c-6e1cf4add605', 'iss': 'https://casdoor.dhdx.fun', 'aud': '8f323670e073612794ef', 'preferred_username': 'weijuesen', 'name': '韦矍森', 'email': 'voole@vip.qq.com', 'email_verified': True, 'picture': 'https://cdn.casbin.org/img/casbin.svg', 'phone': '19977899008', 'groups': ['dahua/yunzhongtai']}
[2025-12-10 16:36:13,361] INFO in auth: 更新用户信息: 韦矍森(19977899008)
[2025-12-10 16:36:13,364] INFO in auth: 用户 韦矍森(19977899008) 通过 Casdoor 登录成功
[2025-12-10 16:36:13,452] INFO in dashboard: 用户 韦矍森 访问仪表盘页面
[2025-12-10 16:36:16,325] INFO in auth: 用户 韦矍森(19977899008) 登出
[2025-12-10 16:38:28,194] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-10 16:38:29,004] INFO in auth: Casdoor 用户信息: {'sub': '798f4436-fbb6-45f4-bf0c-6e1cf4add605', 'iss': 'https://casdoor.dhdx.fun', 'aud': '8f323670e073612794ef', 'preferred_username': 'weijuesen', 'name': '韦矍森', 'email': 'voole@vip.qq.com', 'email_verified': True, 'picture': 'https://cdn.casbin.org/img/casbin.svg', 'phone': '19977899008', 'groups': ['dahua/yunzhongtai']}
[2025-12-10 16:38:29,008] INFO in auth: 更新用户信息: 韦矍森(19977899008)
[2025-12-10 16:38:29,010] INFO in auth: 用户 韦矍森(19977899008) 通过 Casdoor 登录成功
[2025-12-10 16:38:29,099] INFO in dashboard: 用户 韦矍森 访问仪表盘页面
[2025-12-10 16:38:31,444] INFO in auth: 用户 韦矍森(19977899008) 登出
[2025-12-10 16:42:35,542] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-10 16:42:45,468] INFO in auth: Casdoor 用户信息: {'sub': '798f4436-fbb6-45f4-bf0c-6e1cf4add605', 'iss': 'https://casdoor.dhdx.fun', 'aud': '8f323670e073612794ef', 'preferred_username': 'weijuesen', 'name': '韦矍森', 'email': 'voole@vip.qq.com', 'email_verified': True, 'picture': 'https://cdn.casbin.org/img/casbin.svg', 'phone': '19977899008', 'groups': ['dahua/yunzhongtai']}
[2025-12-10 16:42:45,473] INFO in auth: 更新用户信息: 韦矍森(19977899008)
[2025-12-10 16:42:45,475] INFO in auth: 用户 韦矍森(19977899008) 通过 Casdoor 登录成功
[2025-12-10 16:42:45,542] INFO in dashboard: 用户 韦矍森 访问仪表盘页面
[2025-12-10 16:42:47,439] INFO in auth: 用户 韦矍森(19977899008) 登出
[2025-12-10 16:42:52,685] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-10 16:43:21,587] INFO in auth: Casdoor 用户信息: {'sub': '798f4436-fbb6-45f4-bf0c-6e1cf4add605', 'iss': 'https://casdoor.dhdx.fun', 'aud': '8f323670e073612794ef', 'preferred_username': 'weijuesen', 'name': '韦矍森', 'email': 'voole@vip.qq.com', 'email_verified': True, 'picture': 'https://cdn.casbin.org/img/casbin.svg', 'phone': '19977899008', 'groups': ['dahua/yunzhongtai']}
[2025-12-10 16:43:21,590] INFO in auth: 更新用户信息: 韦矍森(19977899008)
[2025-12-10 16:43:21,591] INFO in auth: 用户 韦矍森(19977899008) 通过 Casdoor 登录成功
[2025-12-10 16:43:21,651] INFO in dashboard: 用户 韦矍森 访问仪表盘页面
[2025-12-10 16:43:23,490] INFO in auth: 用户 韦矍森(19977899008) 登出
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
gateway "uWSGI http 1" has been buried (pid: 1748137)
...gracefully killing workers...
Gracefully killing worker 2 (pid: 1748127)...
Gracefully killing worker 4 (pid: 1748130)...
Gracefully killing worker 1 (pid: 1748124)...
Gracefully killing worker 3 (pid: 1748128)...
worker 1 buried after 1 seconds
worker 2 buried after 1 seconds
worker 3 buried after 1 seconds
worker 4 buried after 1 seconds
binary reloading uWSGI...
chdir() to /home/v6ole/pyproject/4an
closing all non-uwsgi socket fds > 2 (max_fd = 1024)...
found fd 9 mapped to socket 0 (/home/v6ole/pyproject/4an/uwsgi.sock)
running /home/v6ole/pyproject/venv/bin/uwsgi
[uWSGI] getting INI configuration from /home/v6ole/pyproject/4an/app/uwsgi.ini
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:46:45 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
machine: x86_64
clock source: unix
detected number of CPU cores: 22
current working directory: /home/v6ole/pyproject/4an
detected binary path: /home/v6ole/pyproject/venv/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
chdir() to /home/v6ole/pyproject/4an/app
your processes number limit is 63617
your memory page size is 4096 bytes
*** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers ***
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 0.0.0.0:18019 fd 7
probably another instance of uWSGI is running on the same address (0.0.0.0:18019).
bind(): Address already in use [core/socket.c line 769]
VACUUM: pidfile removed.
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:46:46 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
machine: x86_64
clock source: unix
detected number of CPU cores: 22
current working directory: /home/v6ole/pyproject/4an
writing pidfile to /home/v6ole/pyproject/4an/uwsgi.pid
detected binary path: /home/v6ole/pyproject/venv/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
chdir() to /home/v6ole/pyproject/4an/app
your processes number limit is 63617
your memory page size is 4096 bytes
*** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers ***
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 0.0.0.0:18019 fd 6
uwsgi socket 0 bound to UNIX address /home/v6ole/pyproject/4an/uwsgi.sock fd 9
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
Python version: 3.12.3 (main, Nov 6 2025, 13:44:16) [GCC 13.3.0]
PEP 405 virtualenv detected: /home/v6ole/pyproject/venv
Set PythonHome to /home/v6ole/pyproject/venv
Python main interpreter initialized at 0x7c0234ea3668
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 703440 bytes (686 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
[2025-12-10 16:46:46,862] INFO in app: 应用启动
[2025-12-10 16:46:46,864] INFO in error_handlers: 错误处理器初始化完成
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7c0234ea3668 pid: 1757751 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1757751)
spawned uWSGI worker 1 (pid: 1757894, cores: 2)
spawned uWSGI worker 2 (pid: 1757897, cores: 2)
Python auto-reloader enabled
spawned uWSGI worker 3 (pid: 1757900, cores: 2)
spawned uWSGI worker 4 (pid: 1757903, cores: 2)
*** Stats server enabled on 127.0.0.1:9191 fd: 22 ***
spawned uWSGI http 1 (pid: 1757906)
unable to stat() uwsgi.reload, events will be triggered as soon as the file is created
unable to stat() true, events will be triggered as soon as the file is created
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
[uwsgi-python-reloader] module/file /home/v6ole/pyproject/4an/app/views/auth.py has been modified
gateway "uWSGI http 1" has been buried (pid: 1757906)
...gracefully killing workers...
Gracefully killing worker 2 (pid: 1757897)...
Gracefully killing worker 1 (pid: 1757894)...
Gracefully killing worker 4 (pid: 1757903)...
Gracefully killing worker 3 (pid: 1757900)...
worker 1 buried after 1 seconds
worker 2 buried after 1 seconds
worker 3 buried after 1 seconds
worker 4 buried after 1 seconds
binary reloading uWSGI...
chdir() to /home/v6ole/pyproject/4an
closing all non-uwsgi socket fds > 2 (max_fd = 1024)...
found fd 9 mapped to socket 0 (/home/v6ole/pyproject/4an/uwsgi.sock)
running /home/v6ole/pyproject/venv/bin/uwsgi
[uWSGI] getting INI configuration from /home/v6ole/pyproject/4an/app/uwsgi.ini
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:47:45 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
machine: x86_64
clock source: unix
detected number of CPU cores: 22
current working directory: /home/v6ole/pyproject/4an
detected binary path: /home/v6ole/pyproject/venv/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
chdir() to /home/v6ole/pyproject/4an/app
your processes number limit is 63617
your memory page size is 4096 bytes
*** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers ***
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 0.0.0.0:18019 fd 7
probably another instance of uWSGI is running on the same address (0.0.0.0:18019).
bind(): Address already in use [core/socket.c line 769]
VACUUM: pidfile removed.
*** Starting uWSGI 2.0.31 (64bit) on [Wed Dec 10 16:47:46 2025] ***
compiled with version: 13.3.0 on 26 November 2025 03:29:52
os: Linux-6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025
nodename: fnubserver
machine: x86_64
clock source: unix
detected number of CPU cores: 22
current working directory: /home/v6ole/pyproject/4an
writing pidfile to /home/v6ole/pyproject/4an/uwsgi.pid
detected binary path: /home/v6ole/pyproject/venv/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
chdir() to /home/v6ole/pyproject/4an/app
your processes number limit is 63617
your memory page size is 4096 bytes
*** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers ***
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 0.0.0.0:18019 fd 6
uwsgi socket 0 bound to UNIX address /home/v6ole/pyproject/4an/uwsgi.sock fd 9
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
Python version: 3.12.3 (main, Nov 6 2025, 13:44:16) [GCC 13.3.0]
PEP 405 virtualenv detected: /home/v6ole/pyproject/venv
Set PythonHome to /home/v6ole/pyproject/venv
Python main interpreter initialized at 0x7ed4400a3668
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 703440 bytes (686 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
[2025-12-10 16:47:46,964] INFO in app: 应用启动
[2025-12-10 16:47:46,966] INFO in error_handlers: 错误处理器初始化完成
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7ed4400a3668 pid: 1759947 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1759947)
spawned uWSGI worker 1 (pid: 1760128, cores: 2)
spawned uWSGI worker 2 (pid: 1760131, cores: 2)
spawned uWSGI worker 3 (pid: 1760133, cores: 2)
Python auto-reloader enabled
spawned uWSGI worker 4 (pid: 1760135, cores: 2)
*** Stats server enabled on 127.0.0.1:9191 fd: 22 ***
spawned uWSGI http 1 (pid: 1760140)
unable to stat() uwsgi.reload, events will be triggered as soon as the file is created
unable to stat() true, events will be triggered as soon as the file is created
[2025-12-10 16:50:50,047] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-10 16:50:57,304] INFO in auth: Casdoor 用户信息: {'sub': '798f4436-fbb6-45f4-bf0c-6e1cf4add605', 'iss': 'https://casdoor.dhdx.fun', 'aud': '8f323670e073612794ef', 'preferred_username': 'weijuesen', 'name': '韦矍森', 'email': 'voole@vip.qq.com', 'email_verified': True, 'picture': 'https://cdn.casbin.org/img/casbin.svg', 'phone': '19977899008', 'groups': ['dahua/yunzhongtai']}
[2025-12-10 16:50:57,323] INFO in auth: 更新用户信息: 韦矍森(19977899008)
[2025-12-10 16:50:57,325] INFO in auth: 用户 韦矍森(19977899008) 通过 Casdoor 登录成功
[2025-12-10 16:50:57,422] INFO in dashboard: 用户 韦矍森 访问仪表盘页面
[2025-12-10 16:50:59,221] INFO in auth: 用户 韦矍森(19977899008) 登出
[2025-12-10 16:50:59,354] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-10 16:51:25,161] INFO in auth: 重定向到 Casdoor 授权页面
[2025-12-11 22:23:51,348] INFO in auth: Casdoor 用户信息: {'sub': '66d04f8e-e663-4ee1-a2e9-5777901c6df7', 'iss': 'https://casdoor.dhdx.fun', 'aud': '8f323670e073612794ef', 'preferred_username': 'weijuesen', 'name': '韦矍森', 'email': 'voole@vip.qq.com', 'email_verified': True, 'picture': 'https://cdn.casbin.org/img/casbin.svg', 'phone': '19977899008', 'real_name': '韦矍森', 'roles': ['admin']}
[2025-12-11 22:23:51,367] INFO in auth: 更新用户信息: 韦矍森(19977899008)
[2025-12-11 22:23:51,368] INFO in auth: 用户 韦矍森(19977899008) 通过 Casdoor 登录成功
[2025-12-11 22:23:51,772] INFO in dashboard: 用户 韦矍森 访问仪表盘页面
+1 -1
View File
@@ -1 +1 @@
1759947
2857150