由一个用户登录和另一个用户的访问令牌
login by one user and accesstoken of another user
我已经为基于令牌的身份验证实现了 simpleJWT。我创建了一个简单的 hello world 测试 API。
在测试时,我使用 /rest-auth/login/ 进行记录并使用 /api/token/ 进行生成 - 两者都工作正常。
现在进行测试,我使用用户 XYZ(具有 helloworld api 的访问权限)登录并使用另一个用户 ABC(没有 helloworld api 的访问权限)生成令牌。
现在用户 XYZ 已通过身份验证(正常),但我拥有用户 ABC 的令牌(正常)。
现在,当我使用为使用 ABC 生成的令牌调用 API 时,即使用户 ABC 没有 API 的权限,我也能够访问 helloworld api! !因为有权限的用户XYZ已经登录了。
问题是,当多个用户使用该站点时,总是会出现这种情况。如何解决?下面还提供了一些代码片段:
我的settings.py剪掉了
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
代码基本上是一个为用户进行身份验证的装饰器,如下所示
def user_is_ADM(fun_c):
@wraps(fun_c)
def wrapped(request, *args, **kwargs):
# 1 = ADM
if(request.user and request.user.is_authenticated) : <--- here is the issue
user_data = UserProfile.objects.get(user_id = request.user.id)
# user profile as as a user type
u = user_data.user_type
if u == 1:
return fun_c(request, *args, **kwargs)
else:
raise PermissionDenied
return wrapped
在这种情况下我的策略应该是什么?
编辑
如下修改我的装饰器并且它正在工作。如果我做错了什么,请有人评论
def user_is_ADM(fun_c):
@wraps(fun_c)
def wrapped(request, *args, **kwargs):
juser = get_user(request)
if juser.is_authenticated:
user_jwt = JWTAuthentication().authenticate(Request(request))
if user_jwt is not None:
if request.user == user_jwt[0]:
k = user_jwt[0].userprofile.get_user_type_display()
if k == 'ADM':
return fun_c(request,*args,**kwargs)
else:
raise PermissionDenied
else:
raise PermissionDenied
else:
raise PermissionDenied
else:
raise PermissionDenied
return wrapped
查看此文档https://www.django-rest-framework.org/api-guide/permissions/(自定义权限)
设置一般权限设置 (IsAuthenticated) 时。
真的是对用户进行认证,而不是随时验证用户的权限
class IsAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
"""
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
如果基本的管理员和用户身份验证还不够。你可以实现自定义权限
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
"""
extracted from the documentation
"""
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
"""
add authentication logic and return a boolean value
"""
# ...
# return bool()
在浏览量中
from rest_framework.views import APIView
from modulename.permissions import CustomerAccessPermission
class ExampleView(APIView):
"""
...
"""
permission_classes = (CustomerAccessPermission,)
def get(self, request, format=None):
"""
...
"""
这里是一个带有django认证权限的例子
from typing import Tuple
from rest_framework.permissions import BasePermission
class CustomPermission(BasePermission):
"""
...
"""
list_permissions: Tuple[str] = (
'modelname.view_modelname',
'modelname.add_modelname',
'modelname.change_modelname',
'modelname.delete_modelname',
)
def has_permission(self, request, view) -> bool:
return bool(
request.user.has_perms(self.list_permissions)
or
request.user and request.user.is_staff
or
request.user and request.user.is_superuser
)
总结
关于一般的语法,你不会看到任何变化,你必须在视图中导入你的权限或装饰器,不同之处在于运行时和 django 评估权限的方式
请记住,装饰器只不过是 func(func()) 的一种概括方式。
所以你应该总是评估视图并调用你的装饰器修改的方法
相反,此框架中的权限始终定义为权限列表 类。在执行视图的主体之前,验证列表中的每个权限。如果任何权限验证失败,将产生异常。权限被拒绝或异常。将生成未经身份验证的异常,并且不会执行视图的主体。 (查阅文档以获得完整解释)
您应该评估哪种方法最适合您的情况(性能、语法等)。
# you can set your permission in the general settings to avoid importing into each file
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'modulename.permissions.CustomPermission',
),
# ...
}
我已经为基于令牌的身份验证实现了 simpleJWT。我创建了一个简单的 hello world 测试 API。
在测试时,我使用 /rest-auth/login/ 进行记录并使用 /api/token/ 进行生成 - 两者都工作正常。
现在进行测试,我使用用户 XYZ(具有 helloworld api 的访问权限)登录并使用另一个用户 ABC(没有 helloworld api 的访问权限)生成令牌。
现在用户 XYZ 已通过身份验证(正常),但我拥有用户 ABC 的令牌(正常)。
现在,当我使用为使用 ABC 生成的令牌调用 API 时,即使用户 ABC 没有 API 的权限,我也能够访问 helloworld api! !因为有权限的用户XYZ已经登录了。
问题是,当多个用户使用该站点时,总是会出现这种情况。如何解决?下面还提供了一些代码片段:
我的settings.py剪掉了
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
代码基本上是一个为用户进行身份验证的装饰器,如下所示
def user_is_ADM(fun_c):
@wraps(fun_c)
def wrapped(request, *args, **kwargs):
# 1 = ADM
if(request.user and request.user.is_authenticated) : <--- here is the issue
user_data = UserProfile.objects.get(user_id = request.user.id)
# user profile as as a user type
u = user_data.user_type
if u == 1:
return fun_c(request, *args, **kwargs)
else:
raise PermissionDenied
return wrapped
在这种情况下我的策略应该是什么?
编辑 如下修改我的装饰器并且它正在工作。如果我做错了什么,请有人评论
def user_is_ADM(fun_c):
@wraps(fun_c)
def wrapped(request, *args, **kwargs):
juser = get_user(request)
if juser.is_authenticated:
user_jwt = JWTAuthentication().authenticate(Request(request))
if user_jwt is not None:
if request.user == user_jwt[0]:
k = user_jwt[0].userprofile.get_user_type_display()
if k == 'ADM':
return fun_c(request,*args,**kwargs)
else:
raise PermissionDenied
else:
raise PermissionDenied
else:
raise PermissionDenied
else:
raise PermissionDenied
return wrapped
查看此文档https://www.django-rest-framework.org/api-guide/permissions/(自定义权限)
设置一般权限设置 (IsAuthenticated) 时。 真的是对用户进行认证,而不是随时验证用户的权限
class IsAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
"""
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
如果基本的管理员和用户身份验证还不够。你可以实现自定义权限
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
"""
extracted from the documentation
"""
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
"""
add authentication logic and return a boolean value
"""
# ...
# return bool()
在浏览量中
from rest_framework.views import APIView
from modulename.permissions import CustomerAccessPermission
class ExampleView(APIView):
"""
...
"""
permission_classes = (CustomerAccessPermission,)
def get(self, request, format=None):
"""
...
"""
这里是一个带有django认证权限的例子
from typing import Tuple
from rest_framework.permissions import BasePermission
class CustomPermission(BasePermission):
"""
...
"""
list_permissions: Tuple[str] = (
'modelname.view_modelname',
'modelname.add_modelname',
'modelname.change_modelname',
'modelname.delete_modelname',
)
def has_permission(self, request, view) -> bool:
return bool(
request.user.has_perms(self.list_permissions)
or
request.user and request.user.is_staff
or
request.user and request.user.is_superuser
)
总结
关于一般的语法,你不会看到任何变化,你必须在视图中导入你的权限或装饰器,不同之处在于运行时和 django 评估权限的方式
请记住,装饰器只不过是 func(func()) 的一种概括方式。 所以你应该总是评估视图并调用你的装饰器修改的方法
相反,此框架中的权限始终定义为权限列表 类。在执行视图的主体之前,验证列表中的每个权限。如果任何权限验证失败,将产生异常。权限被拒绝或异常。将生成未经身份验证的异常,并且不会执行视图的主体。 (查阅文档以获得完整解释)
您应该评估哪种方法最适合您的情况(性能、语法等)。
# you can set your permission in the general settings to avoid importing into each file
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'modulename.permissions.CustomPermission',
),
# ...
}