stock-backend / app /api /auth.py
fromozuzhouzzz
feat(auth): 添加 token 刷新和会话检查功能
a566f15
Raw
History Blame Contribute Delete
6.57 kB
from flask import jsonify, request, current_app
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from app.models.user import User
from app.api import bp
from app import db
from flask_cors import cross_origin
import traceback
@bp.route('/auth/check_db', methods=['GET'])
@cross_origin()
def check_db():
"""检查数据库状态"""
try:
user_count = User.query.count()
users = User.query.all()
user_list = [{
'id': user.id,
'username': user.username,
'role': user.role,
'store_id': user.store_id
} for user in users]
current_app.logger.info(f"Found {user_count} users in database")
return jsonify({
'user_count': user_count,
'users': user_list
})
except Exception as e:
current_app.logger.error(f"Database check error: {str(e)}")
current_app.logger.exception("Full exception details:")
return jsonify({"message": "Database error"}), 500
@bp.route('/auth/login', methods=['POST', 'OPTIONS'])
@cross_origin(supports_credentials=True)
def login():
"""用户登录"""
if request.method == 'OPTIONS':
return '', 200
try:
current_app.logger.debug("Received login request")
current_app.logger.debug(f"Request headers: {request.headers}")
data = request.get_json()
current_app.logger.debug(f"Request data: {request.get_data(as_text=True)}")
current_app.logger.debug(f"Parsed request data: {data}")
if not data or 'username' not in data or 'password' not in data:
return jsonify({'message': 'Missing username or password'}), 400
user = User.query.filter_by(username=data['username']).first()
current_app.logger.debug(f"Found user: {bool(user)}")
if user and user.check_password(data['password']):
# 将用户ID转换为字符串
access_token = create_access_token(identity=str(user.id))
current_app.logger.info("Login successful")
response_data = {
'access_token': access_token,
'user': {
'id': user.id,
'username': user.username,
'role': user.role,
'store_id': user.store_id
}
}
current_app.logger.debug(f"Response data: {response_data}")
return jsonify(response_data)
else:
return jsonify({'message': 'Invalid username or password'}), 401
except Exception as e:
current_app.logger.error(f"Login error: {str(e)}")
current_app.logger.exception("Full exception details:")
return jsonify({"message": "Internal server error"}), 500
@bp.route('/auth/register', methods=['POST'])
def register():
data = request.get_json()
if User.query.filter_by(username=data['username']).first():
return jsonify({'message': 'Username already exists'}), 400
user = User(
username=data['username'],
role=data['role'],
store_id=data.get('store_id')
)
user.set_password(data['password'])
db.session.add(user)
db.session.commit()
return jsonify({
'message': 'User registered successfully',
'user': {
'id': user.id,
'username': user.username,
'role': user.role
}
}), 201
@bp.route('/auth/change-password', methods=['POST'])
@jwt_required()
@cross_origin()
def change_password():
"""用户修改自己的密码"""
try:
current_user_id = get_jwt_identity()
user = User.query.get(current_user_id)
if not user:
return jsonify({'message': 'User not found'}), 404
data = request.get_json()
if not data or 'old_password' not in data or 'new_password' not in data:
return jsonify({'message': 'Missing old or new password'}), 400
# 验证旧密码
if not user.check_password(data['old_password']):
return jsonify({'message': 'Old password is incorrect'}), 400
# 设置新密码
user.set_password(data['new_password'])
db.session.commit()
return jsonify({'message': 'Password changed successfully'})
except Exception as e:
current_app.logger.error(f"Change password error: {str(e)}")
current_app.logger.exception("Full exception details:")
db.session.rollback()
return jsonify({"message": "Internal server error"}), 500
@bp.route('/auth/refresh-token', methods=['POST'])
@jwt_required()
@cross_origin()
def refresh_token():
"""刷新token"""
try:
# 从JWT中获取用户ID
current_user_id = get_jwt_identity()
# 验证用户是否存在
user = User.query.get(current_user_id)
if not user:
current_app.logger.warning(f"Token refresh failed: User {current_user_id} not found")
return jsonify({'message': 'Invalid user'}), 401
# 创建新的访问令牌
new_access_token = create_access_token(identity=str(user.id))
current_app.logger.info(f"Token refreshed for user {user.username}")
return jsonify({'access_token': new_access_token})
except Exception as e:
current_app.logger.error(f"Token refresh error: {str(e)}")
current_app.logger.exception("Full exception details:")
return jsonify({"message": "Token refresh failed"}), 500
@bp.route('/auth/check-session', methods=['GET'])
@jwt_required()
@cross_origin()
def check_session():
"""检查会话状态"""
try:
# 从JWT中获取用户ID
current_user_id = get_jwt_identity()
# 验证用户是否存在
user = User.query.get(current_user_id)
if not user:
current_app.logger.warning(f"Session check failed: User {current_user_id} not found")
return jsonify({'message': 'Invalid session'}), 401
current_app.logger.info(f"Session valid for user {user.username}")
return jsonify({'status': 'valid'})
except Exception as e:
current_app.logger.error(f"Session check error: {str(e)}")
current_app.logger.exception("Full exception details:")
return jsonify({"message": "Session check failed"}), 500