django - 如何在 django rest 框架中传递多个 authentication_classes?
问题描述
我想创建一个可以使用 client_id 和 client_secret 以及访问令牌访问的 api。要使用 client_id 和 client_secret 访问 api,我有一个自定义身份验证类,如下所示:-
class ClientAuthentication(authentication.BaseAuthentication):
@staticmethod
def get_client_credentials(request):
try:
client_id = request.headers.get('CLIENTID')
client_secret = request.headers.get('CLIENTSECRET')
except:
raise AuthenticationFailed
return {
'client_id': client_id,
'client_secret': client_secret
}
def authenticate(self, request):
credentials = self.get_client_credentials(request)
client_instance = Application.objects.filter(
client_id=credentials['client_id'],
client_secret=credentials['client_secret'],
).first()
if not client_instance:
raise AuthenticationFailed
return client_instance, None
def get_user_application(self, request):
credentials = self.get_client_credentials(request)
application_instance = Application.objects.filter(
client_id=credentials['client_id'],
client_secret=credentials['client_secret'],
).first()
if not application_instance:
raise AuthenticationFailed
return application_instance, None
我想使用的另一个身份验证类是默认的 OAuth2Authentication 我尝试将视图集的 authentication_classes 传递为:
authentication_classes = [ClientAuthentication | OAuth2Authentication]
但这给了我一个错误。我怎样才能做到这一点?
解决方案
您应该通过 authenticate_header 区分身份验证器。当一个 AuthenticationClass(在 authenticate 方法中)读取一个不正确的 authenticate_header 时,应该返回 None,所以请求继续到下一个 Authenticator。例如,在 TokenAuthentication
def authenticate(self, request):
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != self.keyword.lower().encode():
return None
...
如果您不返回 None,则身份验证将引发 APIException,因此不会调用下一个身份验证类。
此外,如果您想使用多个身份验证类,则必须在设置中定义它们,如文档中所示:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
或者在视图中定义它们。
推荐阅读
- python - Python Selenium - 错误:元素不可交互。与网站弹出窗口交互
- python-2.7 - Maya 2020 - 移除渲染设置中的灯光集合实例
- javascript - error Unexpected token = 从 RN 0.64.2 升级到 0.65.1 后
- react-native - 在本机基础中将替代调色板设置为默认主题
- nginx - CORS - 缺少允许来源标头 - Centos7 上的 Nginx
- typescript - 如何在打字稿的嵌套属性名称中使用索引类型
- bootstrap-4 - 如何允许非日期信息进入引导日期选择器,特别是星号?
- python - 如何使用 python 库 unittest 断言异常
- r - 如何使用范围表类在 R 中创建直方图?
- firebase - FirebaseAppError:发出请求时出错:套接字挂起。错误代码:ECONNRESET