修复登录token 存redis问题

pull/2/head
李强 2021-03-15 22:33:40 +08:00
parent c301c9cda2
commit 44c76ada8d
6 changed files with 28 additions and 8 deletions

View File

@ -59,6 +59,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 'vadmin.op_drf.middleware.ApiLoggingMiddleware', # 用于记录API访问日志
] ]
# 允许跨域源 # 允许跨域源
CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL

View File

@ -10,6 +10,7 @@ from ..permission.serializers import UserProfileSerializer, MenuSerializer, Role
RoleCreateUpdateSerializer, DeptTreeSerializer, MenuTreeSerializer, UserProfileCreateUpdateSerializer, \ RoleCreateUpdateSerializer, DeptTreeSerializer, MenuTreeSerializer, UserProfileCreateUpdateSerializer, \
PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer
from ..op_drf.filters import DataLevelPermissionsFilter from ..op_drf.filters import DataLevelPermissionsFilter
from ..system.models import DictDetails
from ..utils.export_excel import export_excel_save_model from ..utils.export_excel import export_excel_save_model
from ..utils.response import SuccessResponse, ErrorResponse from ..utils.response import SuccessResponse, ErrorResponse
@ -56,6 +57,7 @@ class GetRouters(APIView):
# data = '{"msg":"操作成功","code":200,"data":[{"name":"System","path":"/system","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统管理","icon":"system","noCache":false},"children":[{"name":"User","path":"user","hidden":false,"component":"permission/user/index","meta":{"title":"用户管理","icon":"user","noCache":false}},{"name":"Role","path":"role","hidden":false,"component":"permission/role/index","meta":{"title":"角色管理","icon":"peoples","noCache":false}},{"name":"Menu","path":"menu","hidden":false,"component":"permission/menu/index","meta":{"title":"菜单管理","icon":"tree-table","noCache":false}},{"name":"Dept","path":"dept","hidden":false,"component":"permission/dept/index","meta":{"title":"部门管理","icon":"tree","noCache":false}},{"name":"Post","path":"post","hidden":false,"component":"permission/post/index","meta":{"title":"岗位管理","icon":"post","noCache":false}},{"name":"Dict","path":"dict","hidden":false,"component":"system/dict/index","meta":{"title":"字典管理","icon":"dict","noCache":false}},{"name":"Config","path":"config","hidden":false,"component":"system/config/index","meta":{"title":"参数设置","icon":"edit","noCache":false}},{"name":"Notice","path":"notice","hidden":false,"component":"system/notice/index","meta":{"title":"通知公告","icon":"message","noCache":false}},{"name":"Log","path":"log","hidden":false,"redirect":"noRedirect","component":"ParentView","alwaysShow":true,"meta":{"title":"日志管理","icon":"log","noCache":false},"children":[{"name":"Operlog","path":"operlog","hidden":false,"component":"monitor/operlog/index","meta":{"title":"操作日志","icon":"form","noCache":false}},{"name":"Logininfor","path":"logininfor","hidden":false,"component":"monitor/logininfor/index","meta":{"title":"登录日志","icon":"logininfor","noCache":false}}]}]},{"name":"Monitor","path":"/monitor","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统监控","icon":"monitor","noCache":false},"children":[{"name":"Online","path":"online","hidden":false,"component":"monitor/online/index","meta":{"title":"在线用户","icon":"online","noCache":false}},{"name":"Job","path":"job","hidden":false,"component":"monitor/job/index","meta":{"title":"定时任务","icon":"job","noCache":false}},{"name":"Druid","path":"druid","hidden":false,"component":"monitor/druid/index","meta":{"title":"数据监控","icon":"druid","noCache":false}},{"name":"Server","path":"server","hidden":false,"component":"monitor/server/index","meta":{"title":"服务监控","icon":"server","noCache":false}},{"name":"Cache","path":"cache","hidden":false,"component":"monitor/cache/index","meta":{"title":"缓存监控","icon":"redis","noCache":false}}]},{"name":"Tool","path":"/tool","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统工具","icon":"tool","noCache":false},"children":[{"name":"Build","path":"build","hidden":false,"component":"tool/build/index","meta":{"title":"表单构建","icon":"build","noCache":false}},{"name":"Gen","path":"gen","hidden":false,"component":"tool/gen/index","meta":{"title":"代码生成","icon":"code","noCache":false}},{"name":"Swagger","path":"swagger","hidden":false,"component":"tool/swagger/index","meta":{"title":"系统接口","icon":"swagger","noCache":false}}]},{"name":"Http://ruoyi.vip","path":"http://ruoyi.vip","hidden":false,"component":"Layout","meta":{"title":"若依官网","icon":"guide","noCache":false}}]}' # data = '{"msg":"操作成功","code":200,"data":[{"name":"System","path":"/system","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统管理","icon":"system","noCache":false},"children":[{"name":"User","path":"user","hidden":false,"component":"permission/user/index","meta":{"title":"用户管理","icon":"user","noCache":false}},{"name":"Role","path":"role","hidden":false,"component":"permission/role/index","meta":{"title":"角色管理","icon":"peoples","noCache":false}},{"name":"Menu","path":"menu","hidden":false,"component":"permission/menu/index","meta":{"title":"菜单管理","icon":"tree-table","noCache":false}},{"name":"Dept","path":"dept","hidden":false,"component":"permission/dept/index","meta":{"title":"部门管理","icon":"tree","noCache":false}},{"name":"Post","path":"post","hidden":false,"component":"permission/post/index","meta":{"title":"岗位管理","icon":"post","noCache":false}},{"name":"Dict","path":"dict","hidden":false,"component":"system/dict/index","meta":{"title":"字典管理","icon":"dict","noCache":false}},{"name":"Config","path":"config","hidden":false,"component":"system/config/index","meta":{"title":"参数设置","icon":"edit","noCache":false}},{"name":"Notice","path":"notice","hidden":false,"component":"system/notice/index","meta":{"title":"通知公告","icon":"message","noCache":false}},{"name":"Log","path":"log","hidden":false,"redirect":"noRedirect","component":"ParentView","alwaysShow":true,"meta":{"title":"日志管理","icon":"log","noCache":false},"children":[{"name":"Operlog","path":"operlog","hidden":false,"component":"monitor/operlog/index","meta":{"title":"操作日志","icon":"form","noCache":false}},{"name":"Logininfor","path":"logininfor","hidden":false,"component":"monitor/logininfor/index","meta":{"title":"登录日志","icon":"logininfor","noCache":false}}]}]},{"name":"Monitor","path":"/monitor","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统监控","icon":"monitor","noCache":false},"children":[{"name":"Online","path":"online","hidden":false,"component":"monitor/online/index","meta":{"title":"在线用户","icon":"online","noCache":false}},{"name":"Job","path":"job","hidden":false,"component":"monitor/job/index","meta":{"title":"定时任务","icon":"job","noCache":false}},{"name":"Druid","path":"druid","hidden":false,"component":"monitor/druid/index","meta":{"title":"数据监控","icon":"druid","noCache":false}},{"name":"Server","path":"server","hidden":false,"component":"monitor/server/index","meta":{"title":"服务监控","icon":"server","noCache":false}},{"name":"Cache","path":"cache","hidden":false,"component":"monitor/cache/index","meta":{"title":"缓存监控","icon":"redis","noCache":false}}]},{"name":"Tool","path":"/tool","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统工具","icon":"tool","noCache":false},"children":[{"name":"Build","path":"build","hidden":false,"component":"tool/build/index","meta":{"title":"表单构建","icon":"build","noCache":false}},{"name":"Gen","path":"gen","hidden":false,"component":"tool/gen/index","meta":{"title":"代码生成","icon":"code","noCache":false}},{"name":"Swagger","path":"swagger","hidden":false,"component":"tool/swagger/index","meta":{"title":"系统接口","icon":"swagger","noCache":false}}]},{"name":"Http://ruoyi.vip","path":"http://ruoyi.vip","hidden":false,"component":"Layout","meta":{"title":"若依官网","icon":"guide","noCache":false}}]}'
# data = json.loads(data) # data = json.loads(data)
data = [] data = []
sys_show_hide = DictDetails.get_default_dictValue('sys_show_hide')
for ele in menus: for ele in menus:
data.append({ data.append({
'id': ele.get('id'), 'id': ele.get('id'),
@ -64,7 +66,7 @@ class GetRouters(APIView):
'hidden': True if ele.get('visible') != '1' else False, 'hidden': True if ele.get('visible') != '1' else False,
'redirect': ele.get('web_path') if ele.get('isFrame') == '1' else 'noRedirect', 'redirect': ele.get('web_path') if ele.get('isFrame') == '1' else 'noRedirect',
'component': ele.get('component_path') or 'Layout', 'component': ele.get('component_path') or 'Layout',
'meta': {"title": ele.get('name'), "icon": ele.get('icon'), "noCache": ele.get('isCache')}, 'meta': {"title": ele.get('name'), "icon": ele.get('icon'), "noCache": True if ele.get('isCache') == sys_show_hide else False},
'parentId': ele.get('parentId') 'parentId': ele.get('parentId')
}) })
return SuccessResponse(data) return SuccessResponse(data)

View File

@ -12,6 +12,11 @@ class DictDetails(CoreModel):
dict_data = ForeignKey(to='DictData', on_delete=CASCADE, verbose_name="关联字典", db_constraint=False) dict_data = ForeignKey(to='DictData', on_delete=CASCADE, verbose_name="关联字典", db_constraint=False)
remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True) remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True)
@classmethod
def get_default_dictValue(cls, dictName):
instance = DictDetails.objects.filter(dict_data__dictName=dictName, is_default=True).first()
return instance and instance.dictValue
class Meta: class Meta:
verbose_name = '字典详情' verbose_name = '字典详情'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -13,6 +13,7 @@ from rest_framework import exceptions
from rest_framework_jwt.utils import jwt_decode_handler from rest_framework_jwt.utils import jwt_decode_handler
from .decorators import exceptionHandler from .decorators import exceptionHandler
from .jwt_util import jwt_get_session_id
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
User = get_user_model() User = get_user_model()
@ -91,7 +92,8 @@ class RedisOpAuthJwtAuthentication(OpAuthJwtAuthentication):
res = super().authenticate(request) res = super().authenticate(request)
if res: if res:
user, token = res user, token = res
key = f"{self.prefix}_{user.username}" session_id = jwt_get_session_id(token)
key = f"{self.prefix}_{session_id}_{user.username}"
redis_token = cache.get(key) redis_token = cache.get(key)
if redis_token == token: if redis_token == token:
return user, token return user, token

View File

@ -1,6 +1,8 @@
import uuid
from calendar import timegm from calendar import timegm
from datetime import datetime from datetime import datetime
import jwt
from django.conf import settings from django.conf import settings
from django.contrib.auth import login from django.contrib.auth import login
@ -19,10 +21,16 @@ def jwt_response_payload_handler(token, user, request):
} }
def jwt_get_secret_key(payload=None): def jwt_get_session_id(token=None):
"""
获取会话id
:param token:
:return:
"""
payload = jwt.decode(token, None, False)
if isinstance(payload, dict): if isinstance(payload, dict):
return payload.get("secret", "") return payload.get("session_id", "")
return getattr(payload, "secret", "") return getattr(payload, "session_id", "")
def jwt_get_user_secret_key(user): def jwt_get_user_secret_key(user):
@ -37,7 +45,7 @@ def jwt_payload_handler(user):
payload = { payload = {
'user_id': user.pk, 'user_id': user.pk,
'username': user.username, 'username': user.username,
'secret': jwt_get_user_secret_key(user), 'session_id': str(uuid.uuid4()),
'exp': datetime.utcnow() + settings.JWT_AUTH.get('JWT_EXPIRATION_DELTA') 'exp': datetime.utcnow() + settings.JWT_AUTH.get('JWT_EXPIRATION_DELTA')
} }
if settings.JWT_AUTH.get('JWT_ALLOW_REFRESH'): if settings.JWT_AUTH.get('JWT_ALLOW_REFRESH'):

View File

@ -11,6 +11,7 @@ from rest_framework.views import APIView
from rest_framework_jwt.views import ObtainJSONWebToken, jwt_response_payload_handler from rest_framework_jwt.views import ObtainJSONWebToken, jwt_response_payload_handler
from .exceptions import GenException from .exceptions import GenException
from .jwt_util import jwt_get_session_id
from .response import SuccessResponse, ErrorResponse from .response import SuccessResponse, ErrorResponse
# from .jwt_util import jwt_response_payload_handler # from .jwt_util import jwt_response_payload_handler
@ -71,7 +72,8 @@ class LoginView(ObtainJSONWebToken):
response = SuccessResponse(response_data) response = SuccessResponse(response_data)
if token: if token:
username = user.username username = user.username
key = f"{self.prefix}_{username}" session_id = jwt_get_session_id(token)
key = f"{self.prefix}_{session_id}_{username}"
cache.set(key, token, self.ex.total_seconds()) cache.set(key, token, self.ex.total_seconds())
if self.JWT_AUTH_COOKIE and token: if self.JWT_AUTH_COOKIE and token:
expiration = (datetime.datetime.utcnow() + self.ex) expiration = (datetime.datetime.utcnow() + self.ex)