程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)?

开发过程中遇到AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)的问题如何解决?下面主要结合日常开发的经验,给出你关于AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)的解决方法建议,希望对你解决AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)有所启发或帮助;

后端API LoginVIEw(添加了一个强制将csrf令牌添加到主体的装饰器)

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'
)

子域A上的AngularJs单页Web应用程序,使用CORS和CSRF保护与子域B上的Django JsON(REST)API通讯

由于我目前正在进行类似的设置,并且正在努力使CORS与CSRF保护结合使用,因此我想在这里分享自己的经验。

设置 -SPA和API都位于同一域的不同子域上:

  • 子域app.mydomain.com上的AngularJs(1.2.14)单页Web应用程序
  • Django App(1.6.2)在子域API.mydomain.com上实现了JsON REST API AngularJs应用通过与Django API APP相同的项目中的Django应用提供服务,因此它设置了CSRF Coo​​kIE。例如,另请参见如何从一个Django项目运行多个网站

Django API应用程序 -为了使CORS和CSRF保护正常工作,我需要在API后端执行以下操作。

在此应用程序的setTings.py中(Django项目setTings.py的扩展):

  • 添加corsheaders应用程序和中间件以及CSRF中间件:
INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

MIDDLEWARE_CLASSES = (
    ...
    'django.mIDdleware.csrf.CsrfVIEwMIDdleware',
    ...
    'corsheaders.mIDdleware.CorsMIDdleware',
)

另请参阅GitHub上的Django CORS标头

将SPA Webapp的域添加到CORS_ORIGIN_WHITEList

CORS_ORIGIN_WHITEList = [
    ...
    'app.mydomain.com',
    ...
]

将CORS_ALLOW_CREDENTIALS设置为True。这很重要,如果您不这样做,则不会随请求一起发送CSRF Coo​​kIE CORS_ALLOW_CREDENTIALS =真

将suresure_csrf_cookie装饰器添加到处理JsON API请求的视图中:

from django.vIEws.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def myresource(request):
    ...

AngularJs的Django应用程序 -AngularJs应用程序通过同一项目中的Django应用程序提供。此Django应用程序已设置为设置CSRF Coo​​kIE。cookie中的CSRF令牌随后用于对API的请求(因此,该API作为同一Django项目的一部分运行)。

请注意,从Django角度来看,几乎与AngularJs应用程序相关的所有文件都是静态文件。Django应用程序仅需要提供index.HTML即可设置cookie。

在此应用程序的setTings.py中(再次是Django项目setTings.py的扩展),设置CSRF_cookie_DOMAIN,以便子域也可以使用它们:

CSRF_cookie_DOMAIN =“ .mydomain.com”

在vIEws.py中,我只需要渲染一次AngularJs index.HTML文件,再次使用guarantee_csrf_cookie装饰器:

from django.shortcuts import render
from django.vIEws.decorators.csrf import ensure_csrf_cookie

# Create your vIEws here.
@ensure_csrf_cookie
def index(request):
    return render(request, 'index.HTML')

使用AngularJs向API发送请求 -在AngularJs应用配置中,设置以下$ httpProvIDer默认值:

$httpProvIDer.defaults.xsrfcookiename = 'csrftoken';
$httpProvIDer.defaults.xsrfheadername = 'X-CSrftoken';
$httpProvIDer.defaults.withCredentials = true;

同样,请注意withCredentials,这可确保在请求中使用CSRF Coo​​kIE。

下面我展示了如何使用AngularJs $ http服务和Jquery向API发出请求:

$http.post("http://API.mydomain.com/myresource", {
    fIEld1   : ...,
      ...
    fIEldN   : ...
}, {
    headers : {
        "x-csrftoken" : $cookies.csrftoken
    }
});

另请参见ngcookies模块。

使用Jquery(1.11.0):

$.AJAX("http://API.mydomain.com/myresource", {
    type: 'POST',
    dataType : 'Json',
    beforeSend : function(jqXHR, setTings) {
        jqXHR.setrequestheader("x-csrftoken", get_the_csrf_token_from_cookie());
    },
    cache : false,
    ContentType   : "application/Json; charset=UTF-8",
    data : JsON.Stringify({
        fIEld1   : ...,
          ...
        fIEldN   : ...
    }),
    xhrFIElds: {
        withCredentials: true
    }
});

我希望这有帮助!!

解决方法

我正在使用AngularJS和Django Rest Framework + Django CORS Headers开发1页应用程序。

我的问题是,当我联系后端时,“ csrftoken” cookie永远不会显示在浏览器中。

例如:我正在使用帖子进行登录。我正确地获得了“ sessionid” cookie,但是“ csrftoken”却没有出现,因此我无从客户端进行适当的发布,因为由于缺少csrf令牌而被拒绝了。

  • 我已经分析了API的响应标头,而csrftoken却不是。
  • 我直接在其余的API浏览器中查看,并且在那里显示得很好。
  • 只是指出,我可以做我的第一个POST登录,因为Django Rest Framework只对经过身份验证的用户强制CSRF。如果我尝试重新登录,它将失败,因为它显示了“ sessionid” -cookie。
  • 我对绕过CSRF的保护并不感兴趣,就像关于stackoverflow的一些帖子所建议的那样。
    来自前端/后端的一些代码片段。这些都是未完成的代码段,因此请不要挂在编写拙劣的代码上。

后端API LoginView

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,config) {
        console.log('TesTing console error');
        User.isLogged = false;
        User.username = '';
    });
};
}]);

任何有好的技巧/想法/例子的人吗?

大佬总结

以上是大佬教程为你收集整理的AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)全部内容,希望文章能够帮你解决AngularJS + Django Rest Framework + CORS(CSRF Coo​​kie未显示在客户端中)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。