在这里,我们将给大家分享关于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)
- 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 + 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 Cookie。例如,另请参见如何从一个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 Cookie
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 Cookie。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 Cookie。
下面我展示了如何使用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 热身
在正式开始 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数据类型调取数据的过程就完成了,但是会有以下问题:
- 图片,日期格式支持不够(仅会显示图片相对路径)
- 主键JSON字段之外,使得调用起来会不方便
- 文档需要手动写,缺乏规范性且效率低下
- 输入验证缺失 (类似于表单的认证)
- 等等
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)下载
我能够解决它。使用以下代码
组件
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 + 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 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)等相关内容,可以在本站寻找。
本文标签: