0

I did a lot of research on this topic, but it's still not working for me. I set my csrftoken cookie in Django,and it does in the response object.

But in any browser, it says no cookies in this site

Backend:

@ensure_csrf_cookie
def home(request):
    csrf_token = get_token(request)
    response = HttpResponse()
    response = render(request, 'index.html')
    response.set_cookie(key='csrftoken', value=csrf_token)
    return response

Angular:

myapp.config(function($httpProvider){
    //I use this when in angular1.0.x
    //$http.defaults.headers.post['X-CSRFToken'] = $cookies['csrftoken'];
    //now in angular1.2.x I use code below. but none of them works
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});

When I do a POST I get message

Failed to load resource: the server responded with a status of 403 (FORBIDDEN)

Also if I print out header info in the $http error function:

console.log(header('Set-Cookie'));
console.log(header('Access-Control-Allow-Headers'));
console.log(header('Access-Control-Allow-Methods'));

all of these three are null.

I can't figure it why! Especially, it works fine in localhost, either Firefox or Chrome, but in an Apache server, always no cookie in this site.

Is there any setting should I do? Can anyone help my with this issue?

P̲̳x͓L̳
  • 3,615
  • 3
  • 29
  • 37
GGY
  • 73
  • 1
  • 1
  • 6
  • So the problem is probably related to how your apache is defined to store cookies. Check out the [`mod_session_cookie` docs](https://httpd.apache.org/docs/trunk/mod/mod_session_cookie.html) – yuvi Mar 29 '14 at 20:25
  • Thanks yuvi, for your quick replay. It's just I'm using a shared hosting server on bluehost. I'm pretty new to the server side, so what should I check now? Thank you. – GGY Mar 29 '14 at 21:38
  • Actually, if you're using a hosting service, such a simple problem as forgetting to allow cookies and such is not probable. So we're back to looking at your own code. And I'm also guessing the problem is related to angular and not django. Have you seen [this answer on a similar situation](http://stackoverflow.com/a/18159276/2387772)? – yuvi Mar 30 '14 at 07:38
  • Also, [here's another suggestion](https://coderwall.com/p/cb9n1g) you might want to check out. I don't like it much, but I've seen it a couple of times before so maybe it's worth a try – yuvi Mar 30 '14 at 07:42
  • What version of angularjs are you using? According to this answer, you [this answer](http://stackoverflow.com/a/18444493/805427) you need to have version 1.2 or higher to set the csrf token this way – elssar Mar 30 '14 at 08:24
  • @yuvi, hi thanks for the links. I think there must be something wrong I didn't notice because i input the `var token = $('input[name=csrfmiddlewaretoken]').val();console.log(token);` is still undefined! Maybe django didn't send csrf token? or is there any SETTINGS should I do in django? I input the 'django.middleware.csrf.CsrfViewMiddleware'that's for sure. – GGY Mar 30 '14 at 18:52
  • @elssar, thans for your reply. I double check it and I'm sure now I'm using Angular1.2.15. Before this version I used Angular1.0.8 and that time I use $http instead of $httpPorvider to set csrf token. So I think maybe there are something I didn't notice like the order of source filr in index.html or wrong settings in Django?But I have no idea.. – GGY Mar 30 '14 at 18:55
  • You know that when you use `render` you don't need to manually attach the csrf cookie, right? [That's the entire point of using render](http://stackoverflow.com/questions/21371005/django-why-should-i-ever-use-the-render-to-response-at-all) – yuvi Mar 31 '14 at 06:45

3 Answers3

0

I'm not sure this will help, but your view is terribly written. You're trying to force the csrf in about five different ways, and you also have some redundant lines that don't do anything (you do response = HttpResponse() and then override it completely, making that line completely void). so there's a good chance one of them is screwing things over.

The point is - when you use render you don't need to do anything else to enforce the csrf (you know, except for making sure it's enabled). That's the point of using it over render_to_response. Try this much simpler version and see how much it helps:

def home(request):
    return render(request, 'index.html')
Community
  • 1
  • 1
yuvi
  • 18,155
  • 8
  • 56
  • 93
  • Thank you Yuvi. Actually, that's how I wrote my code before I found that issue. After looking up on the internet, I changed my code into the one I posted above just to make sure I have csrf token in the response object. I tried your code again and still not working. Do you think that would be related to the configuration of apache?? Thank you very much! – GGY Apr 02 '14 at 17:54
  • @flyaway I'm not entirely sure... You'll have to provide some additional information. Can you add the actual part where you do the POST request maybe? – yuvi Apr 02 '14 at 18:29
0

Please check the domain of the cookie set by Django.

Be aware of cross-domain requests.

$http docs : Angular provides a mechanism to counter XSRF, When performing XHR requests but will not be set for cross-domain requests.

Here is a small lib that might help you https://github.com/pasupulaphani/angular-csrf-cross-domain/blob/master/dist/angular-csrf-cross-domain.js

phani
  • 1,134
  • 1
  • 11
  • 24
0

Try including the ngCookies module in your application.

myApp.run(function ($http, $cookies) {
    $http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
});
iamsar
  • 1,080
  • 2
  • 15
  • 28