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:
+112
-112
@@ -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'))
|
||||
Reference in New Issue
Block a user