在 django-rest-framework 中,是不是可以同时使用 oauth 和 session 身份验证?
Posted
技术标签:
【中文标题】在 django-rest-framework 中,是不是可以同时使用 oauth 和 session 身份验证?【英文标题】:In django-rest-framework, is it possible to use oauth and session authentication simultaneously?在 django-rest-framework 中,是否可以同时使用 oauth 和 session 身份验证? 【发布时间】:2018-06-17 13:35:35 【问题描述】:这就是我想要做的事情:我正在构建一个金融应用程序。有一个 Web 组件,它使用 Django 模板和 jQuery 处理 AJAX 请求,还有一个移动客户端。
我的目标是对来自网络应用程序的 AJAX 请求使用基于会话的身份验证,使用 django-allauth 进行身份验证,使用 django-oauth-toolkit 对移动应用程序使用 OAUTH2。我正在使用 django-rest-framework 作为端点。
在我添加 OAUTH 中间件/身份验证后端之前,AJAX 行为运行良好。我的view.py
中的这段代码现在在通过 AJAX 调用访问时会提示 401 未经授权,即使用户使用 django-allauth 进行身份验证也是如此。它以前工作过(并且在使用访问令牌通过 curl 访问时仍然工作):
@api_view(['GET'])
def portfolio(request):
"""
Get account balances, total portfolio value in CAD, and balances converted to CAD at current market rates.
"""
try:
account = request.user.account
except ObjectDoesNotExist:
return Response(status=Status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = AccountSerializer(account)
return Response(serializer.data)
这里是mysettings.py
的相关位:
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'oauth2_provider.middleware.OAuth2TokenMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django_otp.middleware.OTPMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
AUTHENTICATION_BACKENDS = (
'allauth.account.auth_backends.AuthenticationBackend',
'django.contrib.auth.backends.ModelBackend',
'oauth2_provider.backends.OAuth2Backend',
)
我编写的不使用 django-rest 的旧方法仍然可以正常工作:
@verified_account_required
def get_rates(request):
if request.method == 'POST':
buy_rates,sell_rates = utility_rates()
if request.POST.get('action') == 'buy':
data = buy_rates
else:
data = sell_rates
return JsonResponse(data)
如何同时使用 Django-rest 和两种身份验证类型?还是不可能?
诚然,我对 Django 很陌生 - 所以这里可能有一些我没有正确理解的东西。
【问题讨论】:
【参考方案1】:我在此设置中使用基于类的视图,但我的设置有一个不同:
REST_FRAMEWORK =
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
然后在 API 视图中,我有以下内容:
from rest_framework import viewsets, permissions, authentication
from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope, OAuth2Authentication
from . import models, serializers
class MyViewSet(viewsets.ModelViewSet):
serializer_class = serializers.MySerializer
authentication_classes = [OAuth2Authentication, authentication.SessionAuthentication]
permission_classes = [IsAuthenticatedOrTokenHasScope,]
required_scopes = ['scope',]
一切正常。
但是,确实,在 DRF 设置的 DEFAULT_AUTHENTICATION_CLASSES
中添加 'oauth2_provider.contrib.rest_framework.OAuth2Authentication'
不起作用。可能是 OAuth2 身份验证后端抛出 401,因为它在 AJAX 请求中没有找到 Token,并且 DRF 没有处理它以给 SessionAuthentication 第二次机会。
我希望这能给您在基于函数的视图中使用 OAuth2 的提示。
【讨论】:
以上是关于在 django-rest-framework 中,是不是可以同时使用 oauth 和 session 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
django-rest-framework - 在可浏览的 API 中自动生成表单?
在带有 django-rest-framework 的过滤器中使用自定义方法
如何在 React 中显示来自 django-rest-framework 的错误消息