diff --git a/view .py b/view .py deleted file mode 100644 index 9933d75..0000000 --- a/view .py +++ /dev/null @@ -1,283 +0,0 @@ -import logging -from django.utils.translation import gettext_lazy as _ -from django.conf import settings -from django.contrib import auth -from django.contrib.auth import REDIRECT_FIELD_NAME -from django.contrib.auth import get_user_model -from django.contrib.auth import logout -from django.contrib.auth.forms import AuthenticationForm -from django.contrib.auth.hashers import make_password -from django.http import HttpResponseRedirect, HttpResponseForbidden -from django.http.request import HttpRequest -from django.http.response import HttpResponse -from django.shortcuts import get_object_or_404 -from django.shortcuts import render -from django.urls import reverse -from django.utils.decorators import method_decorator -from django.utils.http import url_has_allowed_host_and_scheme -from django.views import View -from django.views.decorators.cache import never_cache -from django.views.decorators.csrf import csrf_protect -from django.views.decorators.debug import sensitive_post_parameters -from django.views.generic import FormView, RedirectView - -from djangoblog.utils import send_email, get_sha256, get_current_site, generate_code, delete_sidebar_cache -from . import utils -from .forms import RegisterForm, LoginForm, ForgetPasswordForm, ForgetPasswordCodeForm -from .models import BlogUser - -logger = logging.getLogger(__name__) - - -class RegisterView(FormView): - """ - 用户注册视图 - 处理用户注册流程,包括表单验证、用户创建和发送验证邮件 - """ - form_class = RegisterForm - template_name = 'account/registration_form.html' - - @method_decorator(csrf_protect) - def dispatch(self, *args, **kwargs): - """确保视图受到CSRF保护""" - return super(RegisterView, self).dispatch(*args, **kwargs) - - def form_valid(self, form): - """ - 处理有效的注册表单 - 创建非活跃用户,发送邮箱验证邮件 - """ - if form.is_valid(): - # 创建用户但不立即保存到数据库 - user = form.save(False) - user.is_active = False # 邮箱验证前用户不可用 - user.source = 'Register' # 标记用户来源 - user.save(True) # 保存用户到数据库 - - # 获取当前站点信息 - site = get_current_site().domain - - # 生成验证签名,用于验证链接的安全性 - sign = get_sha256(get_sha256(settings.SECRET_KEY + str(user.id))) - - # 调试模式下使用本地地址 - if settings.DEBUG: - site = '127.0.0.1:8000' - - # 构建验证URL - path = reverse('account:result') - url = "http://{site}{path}?type=validation&id={id}&sign={sign}".format( - site=site, path=path, id=user.id, sign=sign) - - # 构建邮件内容 - content = """ -

请点击下面链接验证您的邮箱

- - {url} - - 再次感谢您! -
- 如果上面链接无法打开,请将此链接复制至浏览器。 - {url} - """.format(url=url) - - # 发送验证邮件 - send_email( - emailto=[ - user.email, - ], - title='验证您的电子邮箱', - content=content) - - # 重定向到结果页面 - url = reverse('accounts:result') + \ - '?type=register&id=' + str(user.id) - return HttpResponseRedirect(url) - else: - # 表单无效,重新渲染表单页面 - return self.render_to_response({ - 'form': form - }) - - -class LogoutView(RedirectView): - """ - 用户登出视图 - 处理用户登出操作并清理相关缓存 - """ - url = '/login/' # 登出后重定向的URL - - @method_decorator(never_cache) - def dispatch(self, request, *args, **kwargs): - """确保登出页面不被缓存""" - return super(LogoutView, self).dispatch(request, *args, **kwargs) - - def get(self, request, *args, **kwargs): - """处理GET请求的登出操作""" - logout(request) # 执行登出操作 - delete_sidebar_cache() # 清理侧边栏缓存 - return super(LogoutView, self).get(request, *args, **kwargs) - - -class LoginView(FormView): - """ - 用户登录视图 - 处理用户认证和登录会话管理 - """ - form_class = LoginForm - template_name = 'account/login.html' - success_url = '/' # 登录成功后默认重定向的URL - redirect_field_name = REDIRECT_FIELD_NAME # 重定向字段名 - login_ttl = 2626560 # 一个月的时间(秒),用于"记住我"功能 - - @method_decorator(sensitive_post_parameters('password')) # 保护密码参数 - @method_decorator(csrf_protect) # CSRF保护 - @method_decorator(never_cache) # 禁止缓存 - def dispatch(self, request, *args, **kwargs): - """应用装饰器到视图分发方法""" - return super(LoginView, self).dispatch(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - """向模板上下文添加重定向URL""" - redirect_to = self.request.GET.get(self.redirect_field_name) - if redirect_to is None: - redirect_to = '/' # 默认重定向到首页 - kwargs['redirect_to'] = redirect_to - - return super(LoginView, self).get_context_data(**kwargs) - - def form_valid(self, form): - """处理有效的登录表单""" - # 使用Django的AuthenticationForm进行认证 - form = AuthenticationForm(data=self.request.POST, request=self.request) - - if form.is_valid(): - # 认证成功,清理缓存并记录日志 - delete_sidebar_cache() - logger.info(self.redirect_field_name) - - # 登录用户 - auth.login(self.request, form.get_user()) - - # 处理"记住我"功能 - if self.request.POST.get("remember"): - self.request.session.set_expiry(self.login_ttl) - - return super(LoginView, self).form_valid(form) - else: - # 认证失败,重新显示表单 - return self.render_to_response({ - 'form': form - }) - - def get_success_url(self): - """获取登录成功后重定向的URL""" - redirect_to = self.request.POST.get(self.redirect_field_name) - - # 验证重定向URL的安全性 - if not url_has_allowed_host_and_scheme( - url=redirect_to, allowed_hosts=[ - self.request.get_host()]): - redirect_to = self.success_url # 不安全的URL使用默认URL - - return redirect_to - - -def account_result(request): - """ - 账户操作结果页面 - 处理注册结果和邮箱验证 - """ - type = request.GET.get('type') # 操作类型:register或validation - id = request.GET.get('id') # 用户ID - - # 获取用户对象,如果不存在返回404 - user = get_object_or_404(get_user_model(), id=id) - logger.info(type) - - # 如果用户已激活,直接重定向到首页 - if user.is_active: - return HttpResponseRedirect('/') - - # 处理注册和验证操作 - if type and type in ['register', 'validation']: - if type == 'register': - # 注册成功页面 - content = ''' - 恭喜您注册成功,一封验证邮件已经发送到您的邮箱,请验证您的邮箱后登录本站。 - ''' - title = '注册成功' - else: - # 邮箱验证处理 - c_sign = get_sha256(get_sha256(settings.SECRET_KEY + str(user.id))) - sign = request.GET.get('sign') - - # 验证签名安全性 - if sign != c_sign: - return HttpResponseForbidden() # 签名不匹配,禁止访问 - - # 激活用户账户 - user.is_active = True - user.save() - - content = ''' - 恭喜您已经成功的完成邮箱验证,您现在可以使用您的账号来登录本站。 - ''' - title = '验证成功' - - # 渲染结果页面 - return render(request, 'account/result.html', { - 'title': title, - 'content': content - }) - else: - # 无效的操作类型,重定向到首页 - return HttpResponseRedirect('/') - - -class ForgetPasswordView(FormView): - """ - 忘记密码视图 - 处理密码重置请求 - """ - form_class = ForgetPasswordForm - template_name = 'account/forget_password.html' - - def form_valid(self, form): - """处理有效的密码重置表单""" - if form.is_valid(): - # 根据邮箱查找用户 - blog_user = BlogUser.objects.filter(email=form.cleaned_data.get("email")).get() - # 使用Django的密码哈希器设置新密码 - blog_user.password = make_password(form.cleaned_data["new_password2"]) - blog_user.save() # 保存新密码 - - # 重定向到登录页面 - return HttpResponseRedirect('/login/') - else: - # 表单无效,重新显示表单 - return self.render_to_response({'form': form}) - - -class ForgetPasswordEmailCode(View): - """ - 发送忘记密码验证码视图 - 处理密码重置验证码的发送 - """ - - def post(self, request: HttpRequest): - """处理POST请求,发送密码重置验证码""" - form = ForgetPasswordCodeForm(request.POST) - - # 验证表单数据 - if not form.is_valid(): - return HttpResponse("错误的邮箱") - - to_email = form.cleaned_data["email"] - - # 生成并发送验证码 - code = generate_code() - utils.send_verify_email(to_email, code) # 发送验证邮件 - utils.set_code(to_email, code) # 存储验证码(通常在缓存中) - - return HttpResponse("ok") # 返回成功响应 \ No newline at end of file