首页 文章

Django csrf令牌Angularjs

提问于
浏览
62

我使用mod_wsgi在apache服务器上运行django,以及直接由apache服务的angularjs应用程序,而不是django . 我想对django服务器进行POST调用(运行rest_framework),但我遇到了csrf令牌的问题 .

有没有办法从服务器设置令牌而不将 {% csrf token %} 作为模板的一部分(因为这些页面不通过django)?

  • 我希望能够通过GET请求获取csrf令牌作为cookie .

  • 我希望能够使用csrf令牌cookie值向django服务器发出POST请求 .

5 回答

  • 1

    Django和AngularJS都已经拥有CSRF支持,你的部分非常简单 .

    首先,您需要在Django中启用CSRF,我相信您已经这样做了,如果没有,请关注Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax .

    现在,Django将在第一个GET请求中设置一个名为 csrftoken 的cookie,并期望在以后的POST / PUT / DELETE请求中使用自定义HTTP头 X-CSRFToken .

    对于Angular,它期望名为 XSRF-TOKEN 的cookie并且将使用 X-XSRF-TOKEN 标头执行POST / PUT / DELETE请求,因此您需要进行一些调整以使两者相互依赖:

    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    

    在你的js代码中的某处添加以上两行,module.config()块是一个很好的地方 .

    而已 .

    NOTE: 这是针对角度1.1.5,旧版本可能需要不同的方法 .

    更新:

    由于角度应用程序不是由django提供的,为了让cookie设置,角度应用程序需要首先对django执行GET请求 .

  • 0
    var foo = angular.module('foo', ['bar']);
    
    foo.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    }]);
    

    所有使用$ http的模块服务和控制器都将使用csrf令牌发送请求 .

  • 11

    搜索后,对我有用的是this post,代码如下:

    angular.module( '[your module name]',
        ... [some dependencies] ...
        'ngCookies',
        ... [other dependencies] ...
    )
    .run( function run( $http, $cookies ){
    
        // For CSRF token compatibility with Django
        $http.defaults.headers.post['X-CSRFToken'] = $cookies.get('csrftoken');
    })
    

    这当然是在通过django服务器的GET请求获取cookie之后 .

    我也在这里查看了其他一些答案,包括Ye Liun 's but couldn' t在官方文档中找到任何指定$ httpProvider上xsrf的默认选项的更改,而不是this pull request,这在我写作时对我不起作用这个帖子 .

  • 108

    我为我的AngularJS应用程序创建了一个Django应用程序,与我的(REST)API Django App在同一个Django项目中,它只提供index.html文件(它只是一个sym.link) . 通过这种方式,CSRF Cookie无需额外的GET请求即可设置 .

    请在这里查看我的回答AngularJS Single Page Web Application on Sub-domain A talking to a Django JSON (REST) API on Sub-domain B using CORS and CSRF protection

  • 60

    如果您将Cookie设置为禁止javascript访问,则需要执行以下操作 . 在模板中,在创建django应用程序之前,添加以下内容:

    <script>
        window.csrf_token = "{{ csrf_token }}";
    </script>
    

    在您的角度应用中,添加以下内容:

    angularApp.config(["$httpProvider", function($httpProvider) {
        $httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
    }]);
    

    至少通过Django 1.9,CSRF令牌不会随着每个请求而改变 . 它仅在用户登录时更改 . 如果您正在执行单页角度应用程序,则需要确保在登录/注销时重置令牌,这应该可以正常工作 .

    注意:由于每个请求上的CSRF令牌发生变化,因此目前在Django 1.10或更高版本中不起作用 . 见Pass Django CSRF token to Angular with CSRF_COOKIE_HTTPONLY

相关问题