功能变化: 加入浏览器单点登录
parent
69d8c3efc0
commit
c514a254c7
|
@ -54,6 +54,7 @@ INSTALLED_APPS = [
|
|||
"rest_framework",
|
||||
"django_filters",
|
||||
"corsheaders", # 注册跨域app
|
||||
'rest_framework_simplejwt.token_blacklist',
|
||||
"dvadmin.system",
|
||||
"drf_yasg",
|
||||
"captcha",
|
||||
|
@ -306,12 +307,14 @@ from datetime import timedelta
|
|||
|
||||
SIMPLE_JWT = {
|
||||
# token有效时长
|
||||
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=120),
|
||||
"ACCESS_TOKEN_LIFETIME": timedelta(seconds=10),
|
||||
# token刷新后的有效时间
|
||||
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
|
||||
# 设置前缀
|
||||
"AUTH_HEADER_TYPES": ("JWT",),
|
||||
"ROTATE_REFRESH_TOKENS": True,
|
||||
'BLACKLIST_AFTER_ROTATION': True,
|
||||
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
|
||||
}
|
||||
|
||||
# ====================================#
|
||||
|
@ -387,6 +390,8 @@ SYSTEM_CONFIG = {}
|
|||
# 字典配置
|
||||
DICTIONARY_CONFIG = {}
|
||||
|
||||
|
||||
|
||||
# ================================================= #
|
||||
# ******************** 插件配置 ******************** #
|
||||
# ================================================= #
|
||||
|
@ -399,4 +404,7 @@ PLUGINS_URL_PATTERNS = []
|
|||
# from dvadmin_upgrade_center.settings import * # 升级中心
|
||||
# from dvadmin_celery.settings import * # celery 异步任务
|
||||
# ...
|
||||
from dvadmin_third.settings import * # 扫码登录
|
||||
from dvadmin_uniapp.settings import * # uniapp后端
|
||||
|
||||
# ********** 一键导入插件配置结束 **********
|
||||
|
|
|
@ -45,6 +45,7 @@ class Users(CoreModel,AbstractUser):
|
|||
blank=True,
|
||||
help_text="关联部门",
|
||||
)
|
||||
last_token = models.CharField(max_length=255,null=True,blank=True, verbose_name="最后一次登录Token", help_text="最后一次登录Token")
|
||||
|
||||
def set_password(self, raw_password):
|
||||
super().set_password(hashlib.md5(raw_password.encode(encoding="UTF-8")).hexdigest())
|
||||
|
|
|
@ -12,7 +12,8 @@ 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 rest_framework_simplejwt.tokens import RefreshToken, AccessToken
|
||||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -105,6 +106,13 @@ class LoginSerializer(TokenObtainPairSerializer):
|
|||
request.user = self.user
|
||||
# 记录登录日志
|
||||
save_login_log(request=request)
|
||||
# 将之前登录用户的token加入黑名单
|
||||
last_token = self.user.last_token
|
||||
if last_token:
|
||||
token = RefreshToken(last_token)
|
||||
token.blacklist()
|
||||
# 将最新的token保存到用户表
|
||||
Users.objects.filter(id=self.user.id).update(last_token=data.get('refresh'))
|
||||
return {"code": 2000, "msg": "请求成功", "data": data}
|
||||
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import traceback
|
|||
from django.db.models import ProtectedError
|
||||
from django.http import Http404
|
||||
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed
|
||||
from rest_framework.status import HTTP_407_PROXY_AUTHENTICATION_REQUIRED, HTTP_401_UNAUTHORIZED
|
||||
from rest_framework.views import set_rollback, exception_handler
|
||||
|
||||
from dvadmin.utils.json_response import ErrorResponse
|
||||
|
@ -33,6 +34,12 @@ def CustomExceptionHandler(ex, context):
|
|||
# 调用默认的异常处理函数
|
||||
response = exception_handler(ex, context)
|
||||
if isinstance(ex, AuthenticationFailed):
|
||||
if response and response.data.get('detail') =="Given token not valid for any token type":
|
||||
code = 401
|
||||
msg = ex.detail
|
||||
elif response and response.data.get('detail') =="Token is blacklisted":
|
||||
return ErrorResponse(status=HTTP_401_UNAUTHORIZED)
|
||||
else:
|
||||
code = 401
|
||||
msg = ex.detail
|
||||
elif isinstance(ex,Http404):
|
||||
|
|
|
@ -78,12 +78,10 @@ function createService () {
|
|||
// return dataAxios.data
|
||||
return dataAxios
|
||||
case 401:
|
||||
// TODO 置换token 未完善
|
||||
util.cookies.remove('token')
|
||||
util.cookies.remove('uuid')
|
||||
util.cookies.remove('refresh')
|
||||
router.push({ path: '/login' })
|
||||
errorCreate(`${getErrorMessage(dataAxios.msg)}`)
|
||||
refreshTken().then(res => {
|
||||
util.cookies.set('token', res.access)
|
||||
router.push({path:'/index'})
|
||||
})
|
||||
break
|
||||
case 404:
|
||||
dataNotFound(`${dataAxios.msg}`)
|
||||
|
@ -109,13 +107,11 @@ function createService () {
|
|||
error.message = '请求错误'
|
||||
break
|
||||
case 401:
|
||||
refreshTken().then(res => {
|
||||
util.cookies.set('token', res.access)
|
||||
}).catch(e => {
|
||||
router.push({ name: 'login' })
|
||||
router.go(0)
|
||||
error.message = '未认证,请登录'
|
||||
})
|
||||
util.cookies.remove('token')
|
||||
util.cookies.remove('uuid')
|
||||
util.cookies.remove('refresh')
|
||||
router.push({ path: '/login' })
|
||||
error.message = '系统已检测到您的账号在其他地方登录~'
|
||||
break
|
||||
case 403:
|
||||
error.message = '拒绝访问'
|
||||
|
|
|
@ -33,7 +33,8 @@ export default {
|
|||
username,
|
||||
password,
|
||||
captcha,
|
||||
captchaKey
|
||||
captchaKey,
|
||||
refresh: util.cookies.get('refresh') || null
|
||||
})
|
||||
// 设置 cookie 一定要存 uuid 和 token 两个 cookie
|
||||
// 整个系统依赖这两个数据进行校验和存储
|
||||
|
|
Loading…
Reference in New Issue