Files
Flask_web-template/app/routes/auth.py
2024-10-28 20:53:12 +08:00

161 lines
5.2 KiB
Python

from flask import Blueprint, render_template, redirect, url_for, flash, request, current_app
from flask_login import login_user, logout_user, login_required, current_user
from app.services import UserService
from urllib.parse import urlparse
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
"""
用戶登入處理
GET: 顯示登入頁面
POST: 處理登入請求
"""
if current_user.is_authenticated:
return redirect(url_for('main.index'))
if request.method == 'POST':
# 獲取表單數據
credentials = {
'email': request.form.get('email'),
'password': request.form.get('password'),
'remember': bool(request.form.get('remember'))
}
# 驗證用戶
user = UserService.get_user_by_email(credentials['email'])
if not user or not user.check_password(credentials['password']):
flash('電子郵件或密碼錯誤', 'danger')
return redirect(url_for('auth.login'))
# 更新登入時間
success, error = UserService.update_last_login(user.id)
if not success:
current_app.logger.error(f"Failed to update last login time: {error}")
# 登入用戶
login_user(user, remember=credentials['remember'])
flash('登入成功!', 'success')
# 處理重定向
next_page = request.args.get('next')
if not next_page or urlparse(next_page).netloc != '':
next_page = url_for('main.index')
return redirect(next_page)
return render_template('auth/login.html', title='登入')
@auth_bp.route('/register', methods=['GET', 'POST'])
def register():
"""
用戶註冊處理
GET: 顯示註冊頁面
POST: 處理註冊請求
"""
if current_user.is_authenticated:
return redirect(url_for('main.index'))
if request.method == 'POST':
# 獲取註冊資料
user_data = {
'email': request.form.get('email'),
'username': request.form.get('username'),
'password': request.form.get('password'),
'confirm_password': request.form.get('confirm_password')
}
# 驗證密碼
if user_data['password'] != user_data['confirm_password']:
flash('密碼不一致', 'danger')
return redirect(url_for('auth.register'))
# 創建用戶
user, error = UserService.create_user(
username=user_data['username'],
email=user_data['email'],
password=user_data['password']
)
if error:
flash(error, 'danger')
return redirect(url_for('auth.register'))
flash('註冊成功!請登入。', 'success')
return redirect(url_for('auth.login'))
return render_template('auth/register.html', title='註冊')
@auth_bp.route('/logout')
@login_required
def logout():
"""處理用戶登出"""
logout_user()
flash('已登出', 'info')
return redirect(url_for('main.index'))
@auth_bp.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
"""
用戶個人資料管理
GET: 顯示個人資料頁面
POST: 處理個人資料更新
"""
if request.method == 'POST':
action = request.form.get('action')
if action == 'update_profile':
# 處理頭像更新
if 'avatar' in request.files:
file = request.files['avatar']
if file.filename:
success, error = UserService.update_avatar(
user_id=current_user.id,
file=file
) # 移除 app 參數
if not success:
flash(f'頭像更新失敗: {error}', 'danger')
return redirect(url_for('auth.profile'))
# 處理基本資料更新
profile_data = {
'username': request.form.get('username'),
'email': request.form.get('email')
}
success, error = UserService.update_profile(
user_id=current_user.id,
**profile_data
)
flash('個人資料已更新' if success else f'更新失敗: {error}',
'success' if success else 'danger')
elif action == 'update_password':
# 處理密碼更新
password_data = {
'current_password': request.form.get('current_password'),
'new_password': request.form.get('new_password')
}
# 驗證輸入
if not all(password_data.values()):
flash('請填寫所有密碼欄位', 'danger')
return redirect(url_for('auth.profile'))
success, error = UserService.update_password(
user_id=current_user.id,
current_password=password_data['current_password'],
new_password=password_data['new_password']
)
flash('密碼已更新' if success else f'更新失敗: {error}',
'success' if success else 'danger')
return redirect(url_for('auth.profile'))
return render_template('auth/profile.html', title='個人資料')