GVKun编程网logo

AngularJS + Django Rest Framework + CORS(CSRF Cookie未显示在客户端中)(cookie中没有jsessionid)

3

在这里,我们将给大家分享关于AngularJS+DjangoRestFramework+CORS的知识,让您更了解CSRFCookie未显示在客户端中的本质,同时也会涉及到如何更有效地1DjangoR

在这里,我们将给大家分享关于AngularJS + Django Rest Framework + CORS的知识,让您更了解CSRF Cookie未显示在客户端中的本质,同时也会涉及到如何更有效地1 Django REST Framework 开发 ---- 原生 Django View 热身、11 Django REST Framework 针对基于类的视图添加 @csrf_exempt、Angular 8 + Django RestFramework文件(CSV)下载、AngularJS + Django Rest Framework + CORS(客户端未显示CSRF Cookie)的内容。

本文目录一览:

AngularJS + Django Rest Framework + CORS(CSRF Cookie未显示在客户端中)(cookie中没有jsessionid)

AngularJS + Django Rest Framework + CORS(CSRF Cookie未显示在客户端中)(cookie中没有jsessionid)

我正在使用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, status, headers, config) {        console.log(''Testing console error'');        User.isLogged = false;        User.username = '''';    });};}]);

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

答案1

小编典典

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

答案2

小编典典

子域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_cookiedef 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 renderfrom django.views.decorators.csrf import ensure_csrf_cookie# Create your views here.@ensure_csrf_cookiedef 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    }});

我希望这有帮助!!

1 Django REST Framework 开发 ---- 原生 Django View 热身

1 Django REST Framework 开发 ---- 原生 Django View 热身

在正式开始 Django REST Framework 学习之前,先用 django.core.serializers 和原生的 Django View 类来实现一次数据的序列化数据。

 

下面的例子展示了,是如何解决序列化 JSON 数据的,前提:给Products的Model已经创建完

创建 Django 项目,并修改 urls.py 文件:

1 from django.views.generic import TemplateView
2 from product.views import ProductsListView
3 
4 
5 urlpatterns = [
6     url(r''^admin/'', admin.site.urls),
7     url(r''^products/'', ProductsListView.as_view(), name="product-list"),
8 ]

 

创建 view.py 文件并写入如下内容:

 1 import json
 2 
 3 from django.http import JsonResponse
 4 from django.core import serializers
 5 from django.views.generic.base import View
 6 
 7 from products.models import Product
 8 
 9 
10 class ProductListView(View):
11     def get(self, request):
12         products = Product.objects.all()
13         json_data = serializers.serialize(''json'', products)  # 将django model 得到的对象序列化成 json 类型
14         json_data = json.loads(json_data)
15 
16         return JsonResponse(json_data, safe=False)  # safe = False 因为json_data是 non-dict 类型,不然会报错

注:在打开网页显示数据时需下载chrome jsonview插件


这样一个基本的django 使用json数据类型调取数据的过程就完成了,但是会有以下问题:

  1. 图片,日期格式支持不够(仅会显示图片相对路径)
  2. 主键JSON字段之外,使得调用起来会不方便
  3. 文档需要手动写,缺乏规范性且效率低下
  4. 输入验证缺失 (类似于表单的认证)
  5. 等等

 

11 Django REST Framework 针对基于类的视图添加 @csrf_exempt

11 Django REST Framework 针对基于类的视图添加 @csrf_exempt

01 - 在类的 dispatch 方法上使用 @csrf_exempt

from django.views.decorators.csrf import csrf_exempt

class MyView(View):

    def get(self, request):
        return HttpResponse("hi")

    def post(self, request):
        return HttpResponse("hi")

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(MyView, self).dispatch(*args, **kwargs)

02 - 在 urls.py 中配置

from django.conf.urls import url
from django.views.decorators.csrf import csrf_exempt
import views

urlpatterns = [
    url(r''^myview/$'', csrf_exempt(views.MyView.as_view()), name=''myview''),
]

03 - 重新改写其中验证 csrf 的方法

在之前,我们对于 csrf 的处理都是使用的 csrf_exempt ,现在我们的 API 都是使用 Router 来生成了。该怎么办呢?
在 Django 中,一个请求在到达视图之前,会先经过中间件的处理。在 DRF 中,所有的请求会先经过认证处理,如果请求认证通过,则会让请求访问视图,如果认证不通过,请求就无法到达视图。所以,我们采用的方法是重写认证。
在 APIView 中,如果提供了 authentication_classes ,则会使用提供的认证后端来进行认证。如果没有提供,则会使用默认的认证后端。有关的细节我们将会在之后的章节中讨论,大家就先了解到这里。提供 csrf 验证的是一个叫做 SessionAuthentication 的认证后端,我们需要重新改写其中验证 csrf 的方法。
# views.py

from rest_framework.authentication import SessionAuthentication


class CsrfExemptSessionAuthentication(SessionAuthentication):
    """
    去除 CSRF 检查
    """

    def enforce_csrf(self, request):
        return


class MsgCodeViewSet(CreateModelMixin, viewsets.GenericViewSet):

    serializer_class = MsgCodeSerializer
    pagination_class = StandardResultsSetPagination

    # 
    authentication_classes = (CsrfExemptSessionAuthentication, )
    permission_classes = (AllowAny, )

 

Angular 8 + Django RestFramework文件(CSV)下载

Angular 8 + Django RestFramework文件(CSV)下载

我能够解决它。使用以下代码

组件

import * as FileSaver from 'file-saver';

onDownloadClick() 
    {
      this.serviceModule.download().subscribe(
        (res) => {
          let blob = new Blob([res],{ type: 'text/csv' });
          FileSaver.saveAs(blob,"example.csv")
        }
      );
    } 
  

服务

public download(): Observable<any> {
    return this.http
      .get(
        "http://localhost:8000/download_csv/",{ responseType: "arraybuffer" }
      )
  }

希望这对以后的人有帮助!

AngularJS + Django Rest Framework + CORS(客户端未显示CSRF Cookie)

AngularJS + Django Rest Framework + CORS(客户端未显示CSRF Cookie)

我正在使用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 + CORSCSRF Cookie未显示在客户端中的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于1 Django REST Framework 开发 ---- 原生 Django View 热身、11 Django REST Framework 针对基于类的视图添加 @csrf_exempt、Angular 8 + Django RestFramework文件(CSV)下载、AngularJS + Django Rest Framework + CORS(客户端未显示CSRF Cookie)等相关内容,可以在本站寻找。

本文标签: