토큰 기반 인증을 위해 simpleJWT를 구현했습니다. 간단한 hello world 테스트 API를 만들었습니다.
테스트하는 동안 / rest-auth / login /으로 로깅하고 / api / token / 사용을 생성합니다. 둘 다 잘 작동합니다.
이제 테스트를 위해 사용자 XYZ (helloworld api에 대한 액세스 권한이 있음)로 로그인하고 다른 사용자 ABC (helloworld api에 대한 액세스 권한이 없음)를 사용하여 토큰을 생성하고 있습니다.
이제 사용자 XYZ가 인증 (ok)되었지만 사용자 ABC (ok)의 토큰이 있습니다.
이제 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):
"""
...
"""
다음은 장고 인증 권한의 예입니다.
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',
),
# ...
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다