AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie 没有出现在客户端) [英] AngularJS + Django Rest Framework + CORS ( CSRF Cookie not showing up in client )

查看:31
本文介绍了AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie 没有出现在客户端)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AngularJS 和 Django Rest Framework + Django CORS Headers 开发一个单页应用程序.

I am developing a 1-page application in AngularJS using and Django Rest Framework + Django CORS Headers.

我的问题是,当我联系后端时,csrftoken"cookie 从未出现在我的浏览器中.

My problem is that the "csrftoken" cookie never shows up in my browser when I have contacted the backend.

例如:我正在使用帖子进行登录.我正确获得了sessionid"cookie,但csrftoken"从未出现,因此我无法从我的客户那里发布正确的帖子,因为我会因为缺少 csrf 令牌而被拒绝.

For example: I am doing a login using a post. I get the "sessionid" cookie properly but the "csrftoken" never shows up and therefor I cannot do proper posts from my client since I will get denied due the lack of the csrf token.

  • 我已经分析了来自 API 的响应标头,但 csrftoken 不在那里.
  • 我直接查看了其余 API 浏览器,它在那里显示得很好.
  • 只是要指出,我可以执行我的第一次 POST 登录,因为 Django Rest Framework 仅对经过身份验证的用户强制执行 CSRF.如果我尝试重新登录,它将失败,因为它存在sessionid"-cookie.
  • 我对像 stackoverflow 上的一些帖子所建议的那样绕过 CSRF 保护不感兴趣.

来自前端/后端的一些代码片段.这些是未完成的片段,所以不要被写得不好的代码所困扰.

Some code snippets from front/backend. These are unfinnished snippets, so dont get hung up on poorly written code.

class LoginView(APIView):

renderer_classes = (JSONPRenderer, JSONRenderer)

def post(self, request, format=None):
    serializer = LoginSerializer(data=request.DATA)

    if serializer.is_valid():
        userAuth = authenticate(username=serializer.data['username'], password=serializer.data['password'])

        if userAuth:

            if userAuth.is_active:
                login(request, userAuth)

                loggedInUser = AuthUserProfile.objects.get(pk=1)
                serializer = UserProfileSerializer(loggedInUser)

                user = [serializer.data, {'isLogged': True}]



        else:
            user = {'isLogged': False}

        return Response(user, status=status.HTTP_200_OK)

    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

客户端 AngularJS 登录控制器

.controller('LoginCtrl', ['$scope', '$http', 'uService', '$rootScope', function(scope, $http, User, rootScope) {

scope.login = function() {

    var config = {
        method: 'POST',
        withCredentials: true,
        url: rootScope.apiURL+'/user/login/',
        data : scope.loginForm
    };

    $http(config)
    .success(function(data, status, headers, config) {

        if (status == 200) {
            console.log(data[0]); //Test code
            // succefull login
            User.isLogged = true;
            User.username = data.username;

        }
        else {
            console.log(data); //Test code
            User.isLogged = false;
            User.username = '';
        }

    })
    .error(function(data, status, headers, config) {
        console.log('Testing console error');
        User.isLogged = false;
        User.username = '';
    });
};

}]);

有人有什么好的技巧/想法/例子吗?

Anyone with any good tips/ideas/examples?

推荐答案

所以我找到了自己的解决方案,似乎效果很好.

So I found my own solution to this, seems to work great.

这是我的代码的新片段:

This is the new snippets of my code:

class LoginView(APIView):

renderer_classes = (JSONPRenderer, JSONRenderer)

@method_decorator(ensure_csrf_cookie)
def post(self, request, format=None):
    c = {}
    c.update(csrf(request))
    serializer = LoginSerializer(data=request.DATA)

    if serializer.is_valid():
        userAuth = authenticate(username=serializer.data['username'], password=serializer.data['password'])

        if userAuth:

            if userAuth.is_active:
                login(request, userAuth)

                loggedInUser = AuthUserProfile.objects.get(pk=1)
                serializer = UserProfileSerializer(loggedInUser)

                user = [serializer.data, {'isLogged': True}]



        else:
            user = {'isLogged': False}

        return Response(user, status=status.HTTP_200_OK)

    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

AngularJS 客户端(在请求头中添加令牌)

$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;

服务器端设置文件(专门针对 django-cors-headers)

默认添加前5个,但您需要添加X-CSRFToken"以允许使用CORS从客户端到API的此类标头,否则帖子将被拒绝.

CORS_ALLOW_HEADERS = (
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'X-CSRFToken'

)

就是这样!

这篇关于AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie 没有出现在客户端)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆