功能变化: 加入浏览器单点登录

v2.x
猿小天 2023-03-24 16:06:04 +08:00
parent 69d8c3efc0
commit c514a254c7
6 changed files with 39 additions and 18 deletions

View File

@ -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后端
# ********** 一键导入插件配置结束 **********

View File

@ -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())

View File

@ -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}

View File

@ -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):

View File

@ -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 = '拒绝访问'

View File

@ -33,7 +33,8 @@ export default {
username,
password,
captcha,
captchaKey
captchaKey,
refresh: util.cookies.get('refresh') || null
})
// 设置 cookie 一定要存 uuid token 两个 cookie
// 整个系统依赖这两个数据进行校验和存储