django-vue-admin/backend/dvadmin/system/views/login.py

176 lines
5.3 KiB
Python

# -*- coding: utf-8 -*-
"""
@author: 猿小天
@contact: QQ:1638245306
@Created on: 2021/6/2 002 14:20
@Remark:登录视图
"""
import base64
import hashlib
from datetime import datetime, timedelta
from captcha.views import CaptchaStore, captcha_image
from django.contrib import auth
from django.contrib.auth import login
from django.shortcuts import redirect
from django.utils.translation import gettext_lazy as _
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from application import settings
from dvadmin.system.models import Users
from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.validator import CustomValidationError
class CaptchaView(APIView):
authentication_classes = []
permission_classes = []
@swagger_auto_schema(
responses={
'200': openapi.Response('获取成功')
},
security=[],
operation_id='captcha-get',
operation_description='验证码获取',
)
def get(self, request):
hashkey = CaptchaStore.generate_key()
id = CaptchaStore.objects.filter(hashkey=hashkey).first().id
imgage = captcha_image(request, hashkey)
# 将图片转换为base64
image_base = base64.b64encode(imgage.content)
json_data = {"key": id, "image_base": "data:image/png;base64," + image_base.decode('utf-8')}
return SuccessResponse(data=json_data)
class LoginSerializer(TokenObtainPairSerializer):
"""
登录的序列化器:
重写djangorestframework-simplejwt的序列化器
"""
captcha = serializers.CharField(max_length=6, required=False, allow_null=True)
class Meta:
model = Users
fields = "__all__"
read_only_fields = ["id"]
default_error_messages = {
'no_active_account': _('账号/密码不正确')
}
def validate(self, attrs):
captcha = getattr(attrs,'captcha',None)
if settings.CAPTCHA_STATE:
if captcha is None:
raise CustomValidationError("验证码不能为空")
self.image_code = CaptchaStore.objects.filter(
id=self.initial_data['captchaKey']).first()
five_minute_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
if self.image_code and five_minute_ago > self.image_code.expiration:
self.image_code and self.image_code.delete()
raise CustomValidationError('验证码过期')
else:
if self.image_code and (self.image_code.response == captcha or self.image_code.challenge == captcha):
self.image_code and self.image_code.delete()
else:
self.image_code and self.image_code.delete()
raise CustomValidationError("图片验证码错误")
data = super().validate(attrs)
data['name'] = self.user.name
data['userId'] = self.user.id
return {
"code": 2000,
"msg": "请求成功",
"data": data
}
class LoginView(TokenObtainPairView):
"""
登录接口
"""
serializer_class = LoginSerializer
permission_classes = []
class LoginTokenSerializer(TokenObtainPairSerializer):
"""
登录的序列化器:
"""
class Meta:
model = Users
fields = "__all__"
read_only_fields = ["id"]
default_error_messages = {
'no_active_account': _('账号/密码不正确')
}
def validate(self, attrs):
if not getattr(settings, 'LOGIN_NO_CAPTCHA_AUTH', False):
return {
"code": 4000,
"msg": "该接口暂未开通!",
"data": None
}
data = super().validate(attrs)
data['name'] = self.user.name
data['userId'] = self.user.id
return {
"code": 2000,
"msg": "请求成功",
"data": data
}
class LoginTokenView(TokenObtainPairView):
"""
登录获取token接口
"""
serializer_class = LoginTokenSerializer
permission_classes = []
class LogoutView(APIView):
def post(self, request):
return DetailResponse(msg="注销成功")
class ApiLoginSerializer(CustomModelSerializer):
"""接口文档登录-序列化器"""
username = serializers.CharField()
password = serializers.CharField()
class Meta:
model = Users
fields = ['username', 'password']
class ApiLogin(APIView):
"""接口文档的登录接口"""
serializer_class = ApiLoginSerializer
authentication_classes = []
permission_classes = []
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
user_obj = auth.authenticate(request, username=username,
password=hashlib.md5(password.encode(encoding='UTF-8')).hexdigest())
if user_obj:
login(request, user_obj)
return redirect('/')
else:
return ErrorResponse(msg="账号/密码错误")