fix(登录): 🐛 任意密码登录问题
This commit is contained in:
@@ -292,7 +292,7 @@ from datetime import timedelta
|
|||||||
|
|
||||||
SIMPLE_JWT = {
|
SIMPLE_JWT = {
|
||||||
# token有效时长
|
# token有效时长
|
||||||
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=120),
|
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=1),
|
||||||
# token刷新后的有效时间
|
# token刷新后的有效时间
|
||||||
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
|
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
|
||||||
# 设置前缀
|
# 设置前缀
|
||||||
|
|||||||
@@ -63,32 +63,15 @@ class LoginSerializer(TokenObtainPairSerializer):
|
|||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
read_only_fields = ["id"]
|
read_only_fields = ["id"]
|
||||||
|
|
||||||
class LoginView(TokenObtainPairView):
|
default_error_messages = {"no_active_account": _("账号/密码错误")}
|
||||||
"""
|
|
||||||
登录接口
|
|
||||||
"""
|
|
||||||
serializer_class = LoginSerializer
|
|
||||||
permission_classes = []
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def validate(self, attrs):
|
||||||
# username可能携带的不止是用户名,可能还是用户的其它唯一标识 手机号 邮箱
|
captcha = self.initial_data.get("captcha", None)
|
||||||
username = request.data.get('username',None)
|
|
||||||
if username is None:
|
|
||||||
return ErrorResponse(msg="参数错误")
|
|
||||||
password = request.data.get('password',None)
|
|
||||||
if password is None:
|
|
||||||
return ErrorResponse(msg="参数错误")
|
|
||||||
captcha = request.data.get('captcha',None)
|
|
||||||
if captcha is None:
|
|
||||||
return ErrorResponse(msg="参数错误")
|
|
||||||
captchaKey = request.data.get('captchaKey',None)
|
|
||||||
if captchaKey is None:
|
|
||||||
return ErrorResponse(msg="参数错误")
|
|
||||||
if dispatch.get_system_config_values("base.captcha_state"):
|
if dispatch.get_system_config_values("base.captcha_state"):
|
||||||
if captcha is None:
|
if captcha is None:
|
||||||
raise CustomValidationError("验证码不能为空")
|
raise CustomValidationError("验证码不能为空")
|
||||||
self.image_code = CaptchaStore.objects.filter(
|
self.image_code = CaptchaStore.objects.filter(
|
||||||
id=captchaKey
|
id=self.initial_data["captchaKey"]
|
||||||
).first()
|
).first()
|
||||||
five_minute_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
|
five_minute_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
|
||||||
if self.image_code and five_minute_ago > self.image_code.expiration:
|
if self.image_code and five_minute_ago > self.image_code.expiration:
|
||||||
@@ -103,36 +86,98 @@ class LoginView(TokenObtainPairView):
|
|||||||
else:
|
else:
|
||||||
self.image_code and self.image_code.delete()
|
self.image_code and self.image_code.delete()
|
||||||
raise CustomValidationError("图片验证码错误")
|
raise CustomValidationError("图片验证码错误")
|
||||||
try:
|
data = super().validate(attrs)
|
||||||
# 手动通过 user 签发 jwt-token
|
data["name"] = self.user.name
|
||||||
user = Users.objects.get(username=username)
|
data["userId"] = self.user.id
|
||||||
except:
|
data["avatar"] = self.user.avatar
|
||||||
return DetailResponse(msg='该账号未注册')
|
data['user_type'] = self.user.user_type
|
||||||
# 获得用户后,校验密码并签发token
|
dept = getattr(self.user, 'dept', None)
|
||||||
if check_password(make_password(password),user.password):
|
|
||||||
return DetailResponse(msg='密码错误')
|
|
||||||
result = {
|
|
||||||
"name":user.name,
|
|
||||||
"userId":user.id,
|
|
||||||
"avatar":user.avatar,
|
|
||||||
}
|
|
||||||
dept = getattr(user, 'dept', None)
|
|
||||||
if dept:
|
if dept:
|
||||||
result['dept_info'] = {
|
data['dept_info'] = {
|
||||||
'dept_id': dept.id,
|
'dept_id': dept.id,
|
||||||
'dept_name': dept.name,
|
'dept_name': dept.name,
|
||||||
'dept_key': dept.key
|
|
||||||
}
|
}
|
||||||
role = getattr(user, 'role', None)
|
role = getattr(self.user, 'role', None)
|
||||||
if role:
|
if role:
|
||||||
result['role_info'] = role.values('id', 'name', 'key')
|
data['role_info'] = role.values('id', 'name', 'key')
|
||||||
refresh = LoginSerializer.get_token(user)
|
request = self.context.get("request")
|
||||||
result["refresh"] = str(refresh)
|
request.user = self.user
|
||||||
result["access"] = str(refresh.access_token)
|
|
||||||
# 记录登录日志
|
# 记录登录日志
|
||||||
request.user = user
|
|
||||||
save_login_log(request=request)
|
save_login_log(request=request)
|
||||||
return DetailResponse(data=result,msg="获取成功")
|
return {"code": 2000, "msg": "请求成功", "data": data}
|
||||||
|
|
||||||
|
class LoginView(TokenObtainPairView):
|
||||||
|
"""
|
||||||
|
登录接口
|
||||||
|
"""
|
||||||
|
serializer_class = LoginSerializer
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
# def post(self, request, *args, **kwargs):
|
||||||
|
# # username可能携带的不止是用户名,可能还是用户的其它唯一标识 手机号 邮箱
|
||||||
|
# username = request.data.get('username',None)
|
||||||
|
# if username is None:
|
||||||
|
# return ErrorResponse(msg="参数错误")
|
||||||
|
# password = request.data.get('password',None)
|
||||||
|
# if password is None:
|
||||||
|
# return ErrorResponse(msg="参数错误")
|
||||||
|
# captcha = request.data.get('captcha',None)
|
||||||
|
# if captcha is None:
|
||||||
|
# return ErrorResponse(msg="参数错误")
|
||||||
|
# captchaKey = request.data.get('captchaKey',None)
|
||||||
|
# if captchaKey is None:
|
||||||
|
# return ErrorResponse(msg="参数错误")
|
||||||
|
# if dispatch.get_system_config_values("base.captcha_state"):
|
||||||
|
# if captcha is None:
|
||||||
|
# raise CustomValidationError("验证码不能为空")
|
||||||
|
# self.image_code = CaptchaStore.objects.filter(
|
||||||
|
# id=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("图片验证码错误")
|
||||||
|
# try:
|
||||||
|
# # 手动通过 user 签发 jwt-token
|
||||||
|
# user = Users.objects.get(username=username)
|
||||||
|
# except:
|
||||||
|
# return DetailResponse(msg='该账号未注册')
|
||||||
|
# # 获得用户后,校验密码并签发token
|
||||||
|
# print(make_password(password),user.password)
|
||||||
|
# if check_password(make_password(password),user.password):
|
||||||
|
# return DetailResponse(msg='密码错误')
|
||||||
|
# result = {
|
||||||
|
# "name":user.name,
|
||||||
|
# "userId":user.id,
|
||||||
|
# "avatar":user.avatar,
|
||||||
|
# }
|
||||||
|
# dept = getattr(user, 'dept', None)
|
||||||
|
# if dept:
|
||||||
|
# result['dept_info'] = {
|
||||||
|
# 'dept_id': dept.id,
|
||||||
|
# 'dept_name': dept.name,
|
||||||
|
# 'dept_key': dept.key
|
||||||
|
# }
|
||||||
|
# role = getattr(user, 'role', None)
|
||||||
|
# if role:
|
||||||
|
# result['role_info'] = role.values('id', 'name', 'key')
|
||||||
|
# refresh = LoginSerializer.get_token(user)
|
||||||
|
# result["refresh"] = str(refresh)
|
||||||
|
# result["access"] = str(refresh.access_token)
|
||||||
|
# # 记录登录日志
|
||||||
|
# request.user = user
|
||||||
|
# save_login_log(request=request)
|
||||||
|
# return DetailResponse(data=result,msg="获取成功")
|
||||||
|
|
||||||
|
|
||||||
class LoginTokenSerializer(TokenObtainPairSerializer):
|
class LoginTokenSerializer(TokenObtainPairSerializer):
|
||||||
|
|||||||
@@ -11,14 +11,19 @@ import traceback
|
|||||||
|
|
||||||
from django.db.models import ProtectedError
|
from django.db.models import ProtectedError
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed
|
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed, NotAuthenticated
|
||||||
from rest_framework.views import set_rollback
|
from rest_framework.status import HTTP_401_UNAUTHORIZED
|
||||||
|
from rest_framework.views import set_rollback, exception_handler
|
||||||
|
|
||||||
from dvadmin.utils.json_response import ErrorResponse
|
from dvadmin.utils.json_response import ErrorResponse
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomAuthenticationFailed(NotAuthenticated):
|
||||||
|
# 设置 status_code 属性为 400
|
||||||
|
status_code = 400
|
||||||
|
|
||||||
def CustomExceptionHandler(ex, context):
|
def CustomExceptionHandler(ex, context):
|
||||||
"""
|
"""
|
||||||
统一异常拦截处理
|
统一异常拦截处理
|
||||||
@@ -30,9 +35,14 @@ def CustomExceptionHandler(ex, context):
|
|||||||
"""
|
"""
|
||||||
msg = ''
|
msg = ''
|
||||||
code = 4000
|
code = 4000
|
||||||
|
# 调用默认的异常处理函数
|
||||||
|
response = exception_handler(ex, context)
|
||||||
if isinstance(ex, AuthenticationFailed):
|
if isinstance(ex, AuthenticationFailed):
|
||||||
code = 401
|
code = 401
|
||||||
|
code_type = response.data.get('detail').code
|
||||||
|
if code_type == 'no_active_account':
|
||||||
|
code=400
|
||||||
|
return ErrorResponse(status=HTTP_401_UNAUTHORIZED)
|
||||||
msg = ex.detail
|
msg = ex.detail
|
||||||
elif isinstance(ex,Http404):
|
elif isinstance(ex,Http404):
|
||||||
code = 400
|
code = 400
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ export const DictionaryStore = defineStore('Dictionary', {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(childrens)
|
|
||||||
this.data[item.value]=childrens
|
this.data[item.value]=childrens
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { get } from 'lodash-es';
|
import { get } from 'lodash-es';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import type { Action } from 'element-plus'
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { errorLog, errorCreate } from './tools.ts';
|
import { errorLog, errorCreate } from './tools.ts';
|
||||||
// import { env } from "/src/utils/util.env";
|
// import { env } from "/src/utils/util.env";
|
||||||
@@ -58,11 +61,22 @@ function createService() {
|
|||||||
} else {
|
} else {
|
||||||
// 有 code 代表这是一个后端接口 可以进行进一步的判断
|
// 有 code 代表这是一个后端接口 可以进行进一步的判断
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
case 400:
|
||||||
|
Local.clear();
|
||||||
|
Session.clear();
|
||||||
|
errorCreate(`${dataAxios.msg}: ${response.config.url}`);
|
||||||
|
window.location.reload();
|
||||||
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
Local.clear();
|
Local.clear();
|
||||||
Session.clear();
|
Session.clear();
|
||||||
window.location.reload();
|
|
||||||
dataAxios.msg = '登录授权过期,请重新登录';
|
dataAxios.msg = '登录授权过期,请重新登录';
|
||||||
|
ElMessageBox.alert(dataAxios.msg, '提示', {
|
||||||
|
confirmButtonText: 'OK',
|
||||||
|
callback: (action: Action) => {
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
})
|
||||||
errorCreate(`${dataAxios.msg}: ${response.config.url}`);
|
errorCreate(`${dataAxios.msg}: ${response.config.url}`);
|
||||||
break;
|
break;
|
||||||
case 2000:
|
case 2000:
|
||||||
|
|||||||
Reference in New Issue
Block a user