144 lines
4.8 KiB
Python
144 lines
4.8 KiB
Python
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) |