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)