From 4522284714379d66193e92661b0d0789c0372c3f Mon Sep 17 00:00:00 2001
From: lunhun <2077786863@qq.com>
Date: Sun, 12 Oct 2025 22:47:35 +0800
Subject: [PATCH 1/2] =?UTF-8?q?account=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
accounts/forms.py | 136 ++++++++++++++++++++++++++++
accounts/views.py | 219 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 355 insertions(+)
create mode 100644 accounts/forms.py
create mode 100644 accounts/views.py
diff --git a/accounts/forms.py b/accounts/forms.py
new file mode 100644
index 0000000..39c9aa2
--- /dev/null
+++ b/accounts/forms.py
@@ -0,0 +1,136 @@
+from django import forms
+from django.contrib.auth import get_user_model, password_validation
+from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
+from django.core.exceptions import ValidationError
+from django.forms import widgets
+from django.utils.translation import gettext_lazy as _
+from . import utils
+from .models import BlogUser
+
+
+# ------------------------- 登录表单 -------------------------
+class LoginForm(AuthenticationForm):
+ """登录表单类(继承 Django 内置 AuthenticationForm)"""
+
+ def __init__(self, *args, **kwargs):
+ super(LoginForm, self).__init__(*args, **kwargs)
+ # 自定义输入框样式
+ self.fields['username'].widget = widgets.TextInput(
+ attrs={'placeholder': "username", "class": "form-control"})
+ self.fields['password'].widget = widgets.PasswordInput(
+ attrs={'placeholder': "password", "class": "form-control"})
+
+
+# ------------------------- 注册表单 -------------------------
+class RegisterForm(UserCreationForm):
+ """用户注册表单(继承 Django 自带 UserCreationForm)"""
+
+ def __init__(self, *args, **kwargs):
+ super(RegisterForm, self).__init__(*args, **kwargs)
+ # 为每个字段自定义前端样式与提示文本
+ self.fields['username'].widget = widgets.TextInput(
+ attrs={'placeholder': "username", "class": "form-control"})
+ self.fields['email'].widget = widgets.EmailInput(
+ attrs={'placeholder': "email", "class": "form-control"})
+ self.fields['password1'].widget = widgets.PasswordInput(
+ attrs={'placeholder': "password", "class": "form-control"})
+ self.fields['password2'].widget = widgets.PasswordInput(
+ attrs={'placeholder': "repeat password", "class": "form-control"})
+
+ def clean_email(self):
+ """检查邮箱是否已被注册"""
+ email = self.cleaned_data['email']
+ if get_user_model().objects.filter(email=email).exists():
+ raise ValidationError(_("email already exists")) # 抛出重复邮箱异常
+ return email
+
+ class Meta:
+ """指定绑定的模型和表单字段"""
+ model = get_user_model()
+ fields = ("username", "email")
+
+
+# ------------------------- 忘记密码表单 -------------------------
+class ForgetPasswordForm(forms.Form):
+ """用户通过邮箱重置密码的表单"""
+
+ # 新密码输入
+ new_password1 = forms.CharField(
+ label=_("New password"),
+ widget=forms.PasswordInput(
+ attrs={
+ "class": "form-control",
+ 'placeholder': _("New password")
+ }
+ ),
+ )
+
+ # 新密码确认输入
+ new_password2 = forms.CharField(
+ label="确认密码",
+ widget=forms.PasswordInput(
+ attrs={
+ "class": "form-control",
+ 'placeholder': _("Confirm password")
+ }
+ ),
+ )
+
+ # 邮箱输入
+ email = forms.EmailField(
+ label='邮箱',
+ widget=forms.TextInput(
+ attrs={
+ 'class': 'form-control',
+ 'placeholder': _("Email")
+ }
+ ),
+ )
+
+ # 验证码输入
+ code = forms.CharField(
+ label=_('Code'),
+ widget=forms.TextInput(
+ attrs={
+ 'class': 'form-control',
+ 'placeholder': _("Code")
+ }
+ ),
+ )
+
+ # ----------- 字段验证逻辑 -----------
+ def clean_new_password2(self):
+ """验证两次输入的新密码是否一致,并校验密码强度"""
+ password1 = self.data.get("new_password1")
+ password2 = self.data.get("new_password2")
+ if password1 and password2 and password1 != password2:
+ raise ValidationError(_("passwords do not match")) # 两次密码不一致
+ password_validation.validate_password(password2) # 使用Django内置规则验证密码强度
+ return password2
+
+ def clean_email(self):
+ """验证邮箱是否存在于数据库"""
+ user_email = self.cleaned_data.get("email")
+ if not BlogUser.objects.filter(email=user_email).exists():
+ # 这里可以根据项目安全策略决定是否提示“邮箱不存在”
+ raise ValidationError(_("email does not exist"))
+ return user_email
+
+ def clean_code(self):
+ """验证邮箱验证码是否正确或过期"""
+ code = self.cleaned_data.get("code")
+ error = utils.verify(
+ email=self.cleaned_data.get("email"),
+ code=code,
+ )
+ if error: # utils.verify 返回错误信息时表示验证失败
+ raise ValidationError(error)
+ return code
+
+
+# ------------------------- 验证码邮箱发送表单 -------------------------
+class ForgetPasswordCodeForm(forms.Form):
+ """发送邮箱验证码表单,仅校验邮箱格式"""
+ email = forms.EmailField(
+ label=_('Email'),
+ )
diff --git a/accounts/views.py b/accounts/views.py
new file mode 100644
index 0000000..390e1ee
--- /dev/null
+++ b/accounts/views.py
@@ -0,0 +1,219 @@
+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, HttpResponse
+from django.http.request import HttpRequest
+from django.shortcuts import get_object_or_404, 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) # 防止CSRF攻击
+ def dispatch(self, *args, **kwargs):
+ 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'
+
+ # 生成邮箱验证链接
+ 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/' # 登出后跳转页面
+
+ @method_decorator(never_cache) # 禁止页面缓存
+ def dispatch(self, request, *args, **kwargs):
+ return super(LogoutView, self).dispatch(request, *args, **kwargs)
+
+ def get(self, request, *args, **kwargs):
+ 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 = '/' # 登录成功默认跳转首页
+ redirect_field_name = REDIRECT_FIELD_NAME
+ login_ttl = 2626560 # “记住我”有效期(30天)
+
+ @method_decorator(sensitive_post_parameters('password')) # 标记敏感字段
+ @method_decorator(csrf_protect)
+ @method_decorator(never_cache)
+ def dispatch(self, request, *args, **kwargs):
+ return super(LoginView, self).dispatch(request, *args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ """为模板提供重定向参数"""
+ 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):
+ """登录逻辑"""
+ 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):
+ """登录成功后跳转路径校验"""
+ redirect_to = self.request.POST.get(self.redirect_field_name)
+ if not url_has_allowed_host_and_scheme(
+ url=redirect_to, allowed_hosts=[self.request.get_host()]
+ ):
+ redirect_to = self.success_url
+ return redirect_to
+
+
+# ------------------------- 注册与验证结果视图 -------------------------
+def account_result(request):
+ """注册或邮箱验证结果页"""
+ type = request.GET.get('type')
+ id = request.GET.get('id')
+
+ 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()
+ # 更新加密后的新密码
+ 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):
+ 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") # 返回成功响应
From 5854b4eab4b31c99e76c24e39b570415a657fe86 Mon Sep 17 00:00:00 2001
From: lunhun <2077786863@qq.com>
Date: Sun, 12 Oct 2025 23:18:12 +0800
Subject: [PATCH 2/2] =?UTF-8?q?account:=20=E8=A1=A5=E5=85=85=E6=B3=A8?=
=?UTF-8?q?=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
accounts/forms.py | 39 +++++++++---
accounts/views.py | 155 +++++++++++++++++++++++++---------------------
2 files changed, 114 insertions(+), 80 deletions(-)
diff --git a/accounts/forms.py b/accounts/forms.py
index fce4137..39c9aa2 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -8,19 +8,26 @@ from . import utils
from .models import BlogUser
+# ------------------------- 登录表单 -------------------------
class LoginForm(AuthenticationForm):
+ """登录表单类(继承 Django 内置 AuthenticationForm)"""
+
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
+ # 自定义输入框样式
self.fields['username'].widget = widgets.TextInput(
attrs={'placeholder': "username", "class": "form-control"})
self.fields['password'].widget = widgets.PasswordInput(
attrs={'placeholder': "password", "class": "form-control"})
+# ------------------------- 注册表单 -------------------------
class RegisterForm(UserCreationForm):
+ """用户注册表单(继承 Django 自带 UserCreationForm)"""
+
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
-
+ # 为每个字段自定义前端样式与提示文本
self.fields['username'].widget = widgets.TextInput(
attrs={'placeholder': "username", "class": "form-control"})
self.fields['email'].widget = widgets.EmailInput(
@@ -31,17 +38,23 @@ class RegisterForm(UserCreationForm):
attrs={'placeholder': "repeat password", "class": "form-control"})
def clean_email(self):
+ """检查邮箱是否已被注册"""
email = self.cleaned_data['email']
if get_user_model().objects.filter(email=email).exists():
- raise ValidationError(_("email already exists"))
+ raise ValidationError(_("email already exists")) # 抛出重复邮箱异常
return email
class Meta:
+ """指定绑定的模型和表单字段"""
model = get_user_model()
fields = ("username", "email")
+# ------------------------- 忘记密码表单 -------------------------
class ForgetPasswordForm(forms.Form):
+ """用户通过邮箱重置密码的表单"""
+
+ # 新密码输入
new_password1 = forms.CharField(
label=_("New password"),
widget=forms.PasswordInput(
@@ -52,6 +65,7 @@ class ForgetPasswordForm(forms.Form):
),
)
+ # 新密码确认输入
new_password2 = forms.CharField(
label="确认密码",
widget=forms.PasswordInput(
@@ -62,6 +76,7 @@ class ForgetPasswordForm(forms.Form):
),
)
+ # 邮箱输入
email = forms.EmailField(
label='邮箱',
widget=forms.TextInput(
@@ -72,6 +87,7 @@ class ForgetPasswordForm(forms.Form):
),
)
+ # 验证码输入
code = forms.CharField(
label=_('Code'),
widget=forms.TextInput(
@@ -82,36 +98,39 @@ class ForgetPasswordForm(forms.Form):
),
)
+ # ----------- 字段验证逻辑 -----------
def clean_new_password2(self):
+ """验证两次输入的新密码是否一致,并校验密码强度"""
password1 = self.data.get("new_password1")
password2 = self.data.get("new_password2")
if password1 and password2 and password1 != password2:
- raise ValidationError(_("passwords do not match"))
- password_validation.validate_password(password2)
-
+ raise ValidationError(_("passwords do not match")) # 两次密码不一致
+ password_validation.validate_password(password2) # 使用Django内置规则验证密码强度
return password2
def clean_email(self):
+ """验证邮箱是否存在于数据库"""
user_email = self.cleaned_data.get("email")
- if not BlogUser.objects.filter(
- email=user_email
- ).exists():
- # todo 这里的报错提示可以判断一个邮箱是不是注册过,如果不想暴露可以修改
+ if not BlogUser.objects.filter(email=user_email).exists():
+ # 这里可以根据项目安全策略决定是否提示“邮箱不存在”
raise ValidationError(_("email does not exist"))
return user_email
def clean_code(self):
+ """验证邮箱验证码是否正确或过期"""
code = self.cleaned_data.get("code")
error = utils.verify(
email=self.cleaned_data.get("email"),
code=code,
)
- if error:
+ if error: # utils.verify 返回错误信息时表示验证失败
raise ValidationError(error)
return code
+# ------------------------- 验证码邮箱发送表单 -------------------------
class ForgetPasswordCodeForm(forms.Form):
+ """发送邮箱验证码表单,仅校验邮箱格式"""
email = forms.EmailField(
label=_('Email'),
)
diff --git a/accounts/views.py b/accounts/views.py
index ae67aec..390e1ee 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -7,11 +7,9 @@ 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 import HttpResponseRedirect, HttpResponseForbidden, HttpResponse
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.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.http import url_has_allowed_host_and_scheme
@@ -26,147 +24,159 @@ from . import utils
from .forms import RegisterForm, LoginForm, ForgetPasswordForm, ForgetPasswordCodeForm
from .models import BlogUser
-logger = logging.getLogger(__name__)
+logger = logging.getLogger(__name__) # 初始化日志记录器
-# Create your views here.
-
+# ------------------------- 注册视图 -------------------------
class RegisterView(FormView):
+ """用户注册视图"""
form_class = RegisterForm
- template_name = 'account/registration_form.html'
+ template_name = 'account/registration_form.html' # 注册页面模板路径
- @method_decorator(csrf_protect)
+ @method_decorator(csrf_protect) # 防止CSRF攻击
def dispatch(self, *args, **kwargs):
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:
+ 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'
+
+ # 生成邮箱验证链接
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)
+ 请点击下面链接验证您的邮箱
+ {url}
+ 再次感谢您!
+
+ 如果上面链接无法打开,请将此链接复制至浏览器。
+ {url}
+ """.format(url=url)
+
+ # 发送验证邮件
send_email(
- emailto=[
- user.email,
- ],
+ emailto=[user.email],
title='验证您的电子邮箱',
- content=content)
+ content=content
+ )
- url = reverse('accounts:result') + \
- '?type=register&id=' + str(user.id)
+ # 注册成功后跳转到结果页面
+ url = reverse('accounts:result') + '?type=register&id=' + str(user.id)
return HttpResponseRedirect(url)
else:
- return self.render_to_response({
- 'form': form
- })
+ # 验证失败重新渲染表单
+ return self.render_to_response({'form': form})
+# ------------------------- 登出视图 -------------------------
class LogoutView(RedirectView):
- url = '/login/'
+ """用户登出视图"""
+ url = '/login/' # 登出后跳转页面
- @method_decorator(never_cache)
+ @method_decorator(never_cache) # 禁止页面缓存
def dispatch(self, request, *args, **kwargs):
return super(LogoutView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
- logout(request)
- delete_sidebar_cache()
+ 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 = '/'
+ success_url = '/' # 登录成功默认跳转首页
redirect_field_name = REDIRECT_FIELD_NAME
- login_ttl = 2626560 # 一个月的时间
+ login_ttl = 2626560 # “记住我”有效期(30天)
- @method_decorator(sensitive_post_parameters('password'))
+ @method_decorator(sensitive_post_parameters('password')) # 标记敏感字段
@method_decorator(csrf_protect)
@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
-
return super(LoginView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
+ """为模板提供重定向参数"""
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):
+ """登录逻辑"""
form = AuthenticationForm(data=self.request.POST, request=self.request)
-
if form.is_valid():
- delete_sidebar_cache()
+ delete_sidebar_cache() # 清除缓存
logger.info(self.redirect_field_name)
- auth.login(self.request, form.get_user())
- if self.request.POST.get("remember"):
+ 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)
- # return HttpResponseRedirect('/')
else:
- return self.render_to_response({
- 'form': form
- })
+ # 登录失败,重新渲染页面
+ return self.render_to_response({'form': form})
def get_success_url(self):
-
+ """登录成功后跳转路径校验"""
redirect_to = self.request.POST.get(self.redirect_field_name)
if not url_has_allowed_host_and_scheme(
- url=redirect_to, allowed_hosts=[
- self.request.get_host()]):
+ url=redirect_to, allowed_hosts=[self.request.get_host()]
+ ):
redirect_to = self.success_url
return redirect_to
+# ------------------------- 注册与验证结果视图 -------------------------
def account_result(request):
+ """注册或邮箱验证结果页"""
type = request.GET.get('type')
id = request.GET.get('id')
- user = get_object_or_404(get_user_model(), id=id)
+ user = get_object_or_404(get_user_model(), id=id) # 获取用户对象
logger.info(type)
- if user.is_active:
+
+ 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
+ return HttpResponseForbidden() # 签名不符禁止访问
+
+ user.is_active = True # 激活账号
user.save()
content = '''
- 恭喜您已经成功的完成邮箱验证,您现在可以使用您的账号来登录本站。
+ 恭喜您已经成功的完成邮箱验证,您现在可以使用您的账号来登录本站。
'''
title = '验证成功'
+
+ # 渲染结果模板
return render(request, 'account/result.html', {
'title': title,
'content': content
@@ -175,30 +185,35 @@ def account_result(request):
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()
+ # 更新加密后的新密码
blog_user.password = make_password(form.cleaned_data["new_password2"])
blog_user.save()
- return HttpResponseRedirect('/login/')
+ return HttpResponseRedirect('/login/') # 修改成功后跳转登录页
else:
return self.render_to_response({'form': form})
+# ------------------------- 发送邮箱验证码视图 -------------------------
class ForgetPasswordEmailCode(View):
+ """用于发送找回密码邮箱验证码"""
def post(self, request: HttpRequest):
form = ForgetPasswordCodeForm(request.POST)
if not form.is_valid():
- return HttpResponse("错误的邮箱")
- to_email = form.cleaned_data["email"]
+ return HttpResponse("错误的邮箱") # 邮箱格式错误
- code = generate_code()
- utils.send_verify_email(to_email, code)
- utils.set_code(to_email, code)
-
- return HttpResponse("ok")
+ 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") # 返回成功响应