我的问题是,“csrftoken”cookie不会显示在我的浏览器,当我已经联系后端。
例如:我正在使用一个帖子登录。我得到“sessionid”cookie正确,但“csrftoken”从来没有显示,因此我不能做正确的帖子从我的客户端,因为我会因为缺乏csrf令牌而被拒绝。
>我已经分析了响应头从API和csrftoken不是。
>我已经直接看了其余的API浏览器,它显示精致。
>只是为了指出,我可以做我的第一次POST登录,因为Django Rest Framework只为已认证的用户强制CSRF。如果我尝试重新登录,它将失败,因为“sessionid” – 它存在的菜。
>我不会厌烦绕过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 = ''; }); };
}]);
任何人有任何好的提示/想法/例子?
由于我目前正在进行类似的设置,并正在努力让CORS与CSRF保护结合正常工作,我想在这里分享我自己的学习。
设置 – SPA和API都位于同一域的不同子域:
> AngularJS(1.2.14)单个网页应用程序在子域app.mydomain.com上
> Django App(1.6.2)在子域api.mydomain.com上实现了一个JSON REST API
AngularJS应用程序通过Django应用程序在与Django API应用程序相同的项目中,这样它设置一个CSRF Cookie。参见,例如,也是How to run multiple websites from one Django project
Django API应用程序 – 为了获得CORS和CSRF保护工作,我需要在API后端执行以下操作。
在此应用的settings.py(Django项目settings.py的扩展)中:
>添加corsheaders应用程序和中间件以及CSRF中间件:
06000
另见Django CORS headers on GitHub
>将SPA Webapp的域添加到CORS_ORIGIN_WHITELIST
06001
>将CORS_ALLOW_CREDENTIALS设置为True。这很重要,如果你不这样做,没有CSRF cookie将与请求一起发送
CORS_ALLOW_CREDENTIALS = True
向处理JSON API请求的视图中添加ensure_csrf_cookie装饰器:
06002
Django App for AngularJS – AngularJS应用程序通过同一个项目中的Django应用程序提供。此Django应用程序设置为设置CSRF Cookie。来自cookie的CSRF令牌然后用于对API的请求(其因此作为同一Django项目的一部分运行)。
注意,几乎所有与AngularJS应用程序相关的文件都是来自Django透视图的静态文件。 Django应用程序只需要提供index.html来设置cookie。
在settings.py这个应用程序(再次是Django项目settings.py的扩展),设置CSRF_COOKIE_DOMAIN,以便子域也可以使用它们:
CSRF_COOKIE_DOMAIN = “.mydomain.com”
在views.py中,我只需要渲染AngularJS index.html文件,再次使用ensure_csrf_cookie装饰器:
06003
使用AngularJS向API发送请求 – 在AngularJS应用程序配置中设置以下$ httpProvider默认值:
06004
再次注意withCredentials,这确保在请求中使用CSRF Cookie。
下面我展示如何使用AngularJS $ http服务和JQuery向api发出请求:
06005
使用JQuery(1.11.0):
06006
我希望这有帮助!!