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
+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
# 创建全局实例