トークンベースの認証用に 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