Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django DRF令牌身份验证_Django_Authentication_Token_Csrf_Django Rest Framework - Fatal编程技术网

Django DRF令牌身份验证

Django DRF令牌身份验证,django,authentication,token,csrf,django-rest-framework,Django,Authentication,Token,Csrf,Django Rest Framework,我对DRF基于令牌的身份验证有问题。以下是我的登录页代码(登录后): 我使用Django的内置登录视图来验证和登录用户,然后我修改了考虑将令牌放在页眉中。但这也不起作用 这是我的登录代码: #Redirect authenticated users to landing page def custom_login(request): if request.user.is_authenticated(): token, created = Token.objects.get

我对DRF基于令牌的身份验证有问题。以下是我的登录页代码(登录后):

我使用Django的内置登录视图来验证和登录用户,然后我修改了考虑将令牌放在页眉中。但这也不起作用

这是我的登录代码:

#Redirect authenticated users to landing page
def custom_login(request):
    if request.user.is_authenticated():
        token, created = Token.objects.get_or_create(user=request.user)
        request.session['AUTHORIZATION'] = "TOKEN "+token.key
        return redirect(landing)
    else:
        return login(request)
以下是我的DRF设置:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        # 'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}
问题是,当我登录并通过浏览器进入登录页时,DRF不工作,我收到以下错误:

{"detail":"Authentication credentials were not provided."}
原因是请求中不存在自定义DRF头(AUTHENTICATION=TOEKN XXXXXXXXX)

但是,如果我使用Postman并放入自定义头(AUTHENTICATION=TOKEN xxxxxxxxxxx),那么它就可以工作了

我如何解决它

这是否意味着每个视图都需要自定义标题

在使用DRF令牌时,是否会打开CSRF漏洞(这个问题:)


非常感谢

你需要先学习基础知识。什么是HTTP,什么是HTTP头,什么是Django会话(它不是HTTP头,会话的内容不影响头),请阅读关于令牌身份验证的Django REST框架文档

如果要在浏览器中测试视图,请在DRF
DEFAULT\u authentication\u CLASSES
配置变量中显式允许Django会话身份验证。它可以与令牌身份验证共存

除非您使用诸如RESTClient、DHC或REST-Easy之类的插件,否则无法让普通web浏览器将令牌附加到HTTP请求

您正在向Django会话添加令牌,但您已经在DRF中禁用了会话身份验证,即使您启用了它,DRF也不会从Django会话读取令牌,因为API客户端无法向Django会话添加令牌。即使DRF从Django会话读取令牌,也毫无意义,因为客户端无法控制会话的内容。会话变量在服务器上设置,而不是在客户端上设置

REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.IsAuthenticated',
        ],
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',  # enables simple command line authentication
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.TokenAuthentication',
        )
    }
添加“rest\u framework.authentication.SessionAuthentication”在大多数情况下解决了这个问题

备选方案

您可以使用:

'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
   ),
但是现在,为了访问受保护的api URL,您必须包含Authorization:JWT头。

  • 我如何解决它?这是否意味着每个视图都需要自定义标题? TokenAuthentication用于单页应用程序,请求头中的令牌需要由API客户端(邮递员、Javascript或任何其他客户端)在每个请求上提供。在您的情况下,如果您想使用Django视图,您应该激活SessionAuthentication。令牌身份验证和会话身份验证可以共存。 一种方法是将令牌保存在自定义登录视图中的cookie中,并由javascript客户端读取

  • 在使用DRF令牌时,是否会打开CSRF漏洞(这个问题:Django DRF-如何使用令牌身份验证进行CSRF验证)? 对但是有办法确保请求的安全。 根据DRF文件 “如果您在生产中使用令牌身份验证,则必须确保您的API仅通过https可用”。 此外,请确保将设置中的ALLOWED_HOSTS设置为您希望Django响应的域,以便服务器不会响应其他来源的请求。除了像上面提到的JWT这样的令牌身份验证之外,还可以使用其他更安全的身份验证


如果它与curl或postman一起工作,则表示后端没有问题。这当然是客户端代码的问题。您是否查看了对RESTAPI的请求?我建议并确保令牌在标题中传递并且格式正确。

如果我的措辞有点不正确,我很抱歉,我不希望我的浏览器附加任何内容。我想要的是登录,但在登录过程中看不到我的用户名/密码令牌。Django身份验证正在工作,作为一种后备方案,它做得很好。但是,我基于令牌的使用不知怎么地不起作用。重申一下:没有DRF(vanilla Django)一切都可以正常工作,但令牌身份验证无法正常工作。@SGangs我在开始回答时建议先阅读文档。您没有正确使用令牌身份验证,因为您不了解什么是令牌身份验证以及如何使用它。要使用令牌身份验证,您必须:1)创建令牌2)将请求中的令牌传递给
授权
http标头中的API方法。DRF包含使用此页上的令牌身份验证发出请求的确切命令行::
curl-X GEThttp://127.0.0.1:8000/api/example/ -H'授权:令牌9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
再次感谢。但我的观点是,当我使用curl/httpie/postman时,它们是有效的。我不知道当用户填写登录表单并单击登录时会发生什么。这是否会导致调用“gettoken”url,在那里它将获得一个令牌,然后将其重定向到“landing”视图?我不明白这个部分。希望你能帮忙。再次谢谢你,顺便说一句!!我也在努力重读一些东西!!!用户不应该直接与RESTAPI交互。如果需要,DRF支持您在设置中禁用的会话身份验证。只需启用它并在浏览器中使用DRF可浏览API即可。访问您的站点的用户不应该直接与API交互。如果您正在编写一个单页应用程序,您的应用程序应该从相应的DRFAPI端点获取令牌,并将令牌与请求一起传递。
'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
   ),