Django Rest框架中的令牌身份验证在生产环境下无法正常工作。

12

我遇到了一个奇怪的问题,但是我找不到原因。我使用Django 1.7和Django Rest Framework以及令牌身份验证构建了API。在本地主机上一切正常,但是当我尝试调用需要身份验证的API端点时,在生产环境中我会收到403状态代码以及以下消息:{"detail": "未提供身份验证凭据。"}。我做错了什么?

根据文档,我将令牌作为标头发送。这是我的设置文件的样子:

INSTALLED APPLICATIONS = (
    '......',
    'rest_framework',
    'rest_framework.authtoken',
    'rest_framework_swagger',
    'corsheaders',
    '......')

MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.contrib.admindocs.middleware.XViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'admin_reorder.middleware.ModelAdminReorder',
)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny'
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'PAGINATE_BY_PARAM': 'page_size',
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
    'VIEW_DESCRIPTION_FUNCTION': 'rest_framework_swagger.views.get_restructuredtext'
}

REST_SESSION_LOGIN = False
CORS_ORIGIN_ALLOW_ALL = True

1
你是否正确发送了令牌?只有在请求格式错误时才会输出此消息。应该像这样:Authorization: Token 401f7ac837da42b97f613d789819ff93537bee6a - Fanis Despoudis
7
你是否正在使用Apache但没有告诉它转发“Authorization”标头?如果标头缺失或为空,则会触发此错误。 - Kevin Brown-Silva
@FanisDespoudis 我发送的令牌是正确的,在本地工作正常。 - jabez
可能是因为同时列出了SessionAuthentication和TokenAuthentication - django-cors-headers文档中指出,您需要设置CORS_REPLACE_HTTPS_REFERER = True并在django.middleware.csrf.CsrfViewMiddleware之后列出corsheaders.middleware.CorsPostCsrfMiddleware (https://github.com/ottoyiu/django-cors-headers/)。 - Chris Berragan
你能否发布一下你正在使用的调用API端点的代码? - Jonathan Stray
显示剩余2条评论
1个回答

20

对于我来说,问题在于Apache没有将Authorization-Header转发给WSGI-Process。这里是解决方法:

只需添加以下代码:

WSGIPassAuthorization on

将以下内容添加到您的Apache(虚拟主机)配置中。


4
救命稻草!要在AWS ElasticBeanstalk上运行此操作,请添加一个容器命令,例如:03wsgipass: command: 'echo "WSGIPassAuthorization On" >> ../wsgi.conf'。详见https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-container.html#create-deploy-python-custom-container。 - birdsarah
1
非常感谢所有参与此讨论的人。我在Beanstalk上也遇到了这个问题,现在已经解决了。 - Greg Holst
1
我曾经考虑放弃使用基本身份验证而转向django-rest-knox,但现在它已经在我的项目中正常工作了!感谢您的帮助! - Denimar Fernandez
1
我一直找不到我的身份验证与Apache不起作用的解决方案,直到看到了你的评论。救星!非常感谢。 - SJ19
1
你真是太棒了。我之前在Django BE + Vue FE + Apache中遇到了同样的问题,但这个方法解决了它。再次感谢你。 - Paandittya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接