diff --git a/views.py b/views.py
new file mode 100644
index 0000000..886b82d
--- /dev/null
+++ b/views.py
@@ -0,0 +1,218 @@
+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__)
+
+
+#lht: Create your views here.
+
+class RegisterView(FormView):
+ #lht: 用户注册视图
+ form_class = RegisterForm
+ template_name = 'account/registration_form.html'
+
+ @method_decorator(csrf_protect)
+ def dispatch(self, *args, **kwargs):
+ #lht: 处理请求分发,添加CSRF保护装饰器
+ return super(RegisterView, self).dispatch(*args, **kwargs)
+
+ def form_valid(self, form):
+ #lht: 表单验证成功时的处理逻辑
+ if form.is_valid():
+ user = form.save(False)
+ user.is_active = False #lht: 新注册用户默认不激活
+ user.source = 'Register' #lht: 标记来源为注册
+ 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)
+
+ #lht: 构造验证邮件内容
+ 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):
+ #lht: 用户登出视图
+ url = '/login/'
+
+ @method_decorator(never_cache)
+ def dispatch(self, request, *args, **kwargs):
+ #lht: 处理请求分发,添加不缓存装饰器
+ return super(LogoutView, self).dispatch(request, *args, **kwargs)
+
+ def get(self, request, *args, **kwargs):
+ #lht: 处理GET请求,执行登出操作
+ logout(request)
+ delete_sidebar_cache() #lht: 清除侧边栏缓存
+ return super(LogoutView, self).get(request, *args, **kwargs)
+
+
+class LoginView(FormView):
+ #lht: 用户登录视图
+ form_class = LoginForm
+ template_name = 'account/login.html'
+ success_url = '/'
+ redirect_field_name = REDIRECT_FIELD_NAME
+ login_ttl = 2626560 #lht: 登录会话保持时间(一个月)
+
+ @method_decorator(sensitive_post_parameters('password'))
+ @method_decorator(csrf_protect)
+ @method_decorator(never_cache)
+ def dispatch(self, request, *args, **kwargs):
+ #lht: 处理请求分发,添加敏感参数保护、CSRF保护和不缓存装饰器
+ return super(LoginView, self).dispatch(request, *args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ #lht: 获取重定向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):
+ #lht: 表单验证成功时的处理逻辑
+ 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):
+ #lht: 获取登录成功后的跳转URL
+ 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):
+ #lht: 账户操作结果页面
+ 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):
+ #lht: 忘记密码视图
+ form_class = ForgetPasswordForm
+ template_name = 'account/forget_password.html'
+
+ def form_valid(self, form):
+ #lht: 表单验证成功时的处理逻辑
+ 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):
+ #lht: 发送忘记密码验证码视图
+
+ def post(self, request: HttpRequest):
+ #lht: 处理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")