Files
Incidents-Data-Portal/backend/app/blueprints/login/routes.py
T

144 lines
4.8 KiB
Python
Raw Normal View History

2026-07-10 18:55:55 +08:00
from flask import Blueprint, current_app, redirect, request, jsonify
from sqlalchemy.exc import IntegrityError
from app.models import User, Role, UserRole # 导入模型类
from app.utils import verify_password # 导入密码加密工具
from app import db
from flask_jwt_extended import (
create_access_token,
jwt_required,
get_jwt_identity,
) # 导入JWT相关工具
login_bp = Blueprint("login", __name__)
@login_bp.route("/login1", methods=["POST"])
def login():
# 初始化响应结构(避免未定义变量问题)F
response = {"code": 200, "message": "success"}
# 1. 获取登录凭证
data = request.get_json()
username = data.get("username")
password = data.get("password")
# 2. 验证必填字段
if not username or not password:
response["code"] = 400
response["message"] = "用户名和密码不能为空"
return jsonify(response)
# 3. 查询用户(包含状态验证)
user = User.query.filter_by(
username=username, status=1
).first() # 直接过滤启用状态的用户
# 4. 验证用户存在性和密码
if not user or not verify_password(
user.password, password
): # 注意:verify_password(加密密码, 明文密码)
response["code"] = 401
response["message"] = "用户名或密码错误"
return jsonify(response)
# 5. 生成JWT令牌
access_token = create_access_token(identity=str(user.id))
# 6. 查询用户关联的角色(处理多角色情况)
# 方式:查询用户所有角色名称,返回数组
roles = (
db.session.query(Role.name)
.join(UserRole, Role.id == UserRole.role_id)
.filter(UserRole.user_id == user.id) # 关联当前登录用户
.all()
)
print("roles", roles)
# 提取角色名称到数组(如果没有角色,返回空数组)
role_list = [role.name for role in roles] if roles else []
# 7. 按指定格式包装结果
result = {
"accessToken": access_token,
"id": user.id,
"username": user.username,
"nickname": user.username, # 假设nickname用username替代(如果表中有nickname字段可直接替换)
"avatar": user.avatar
or "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", # 默认为空时用默认头像
"roles": role_list, # 角色数组(单角色时为['角色名'],多角色时为['角色1','角色2']
}
result = {"code": 200, "data": {"token": access_token}, "msg": "登录成功"}
return jsonify(result)
@login_bp.route("/info", methods=["GET"])
@jwt_required() # 要求登录状态(使用JWT验证)
def get_user_info():
try:
# 获取当前登录用户的ID(假设使用JWT存储用户ID)
current_user_id = get_jwt_identity()
# 查询数据库获取用户信息
user = User.query.get(current_user_id)
if not user:
return jsonify({"code": 404, "msg": "用户不存在", "data": None}), 404
# 提取用户角色(假设Role模型有name字段存储角色名称)
roles = [role.name for role in user.roles] if user.roles else []
# 构造返回数据
res = {
"code": 200,
"msg": "获取成功",
"data": {
"id": user.id,
"username": user.username,
"nickname": user.username, # 模型中没有nickname字段,暂用username代替
"avatar": user.avatar
or "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", # 默认头像
"roles": roles,
},
}
return jsonify(res)
except Exception as e:
# 异常处理
return (
jsonify({"code": 500, "msg": f"获取用户信息失败:{str(e)}", "data": None}),
500,
)
@login_bp.route("/get_record", methods=["GET"])
def get_record_code():
return jsonify({
"code": 200, # 200表示成功
"msg": "查询成功",
"data": current_app.config['HEADERS_SECRET_KEY'] # 调用模型自带的转字典方法
}), 200
@login_bp.route("/login")
def authorization():
"""
授权入口。
将用户浏览器重定向到 SSO 服务器的授权页面。
"""
# print("login123")
CLIENT_ID = current_app.config["CLIENT_ID"]
HOST = current_app.config["SS0_HOST"]
REDIRECT_URL = current_app.config["REDIRECT_URL"]
# 1. 构造重定向到 SSO 授权页面的 URL
auth_url = (
f"{HOST}v1/auth"
f"?response_type=code"
f"&client_id={CLIENT_ID}"
f"&scope=groups+openid+email+profile"
f"&redirect_uri={REDIRECT_URL}"
)
# print(auth_url)
# 2. 执行重定向
return redirect(auth_url)