Ok, so as you can see I have a Django app going on using csrf. It all works perfectly but, now I want my app to be shown in a iframe (Facebook canvas).
While in my main domain it works, in the Facebook canvas I keep getting this error:
Forbidden (403)
CSRF verification failed. Request aborted.
Reason given for failure:
CSRF token missing or incorrect.
I know I'm missing something, but right now I don't know what is it.
Code:
In settings.py I have this correctly:
FACEBOOK_APP_ID = '***************'
FACEBOOK_API_SECRET = '********************************'
FACEBOOK_EXTENDED_PERMISSIONS = ['email','publish_actions']
I'm using Heroku and in my heroku confing in the heroku toolbelt I have FACEBOOK_APP_ID and FACEBOOK_SECRET also correctly set.
More info:
A friend, really long time ago (nearly two years ago) already had set a Facebook login and a Facebook register working in the app.
I hope this will help you: https://github.com/jjanssen/django-fb-iframe
Django and Facebook do not get along. When embedding a microsite into Facebook it will call an iframe with a POST request. Of course your Django project will return a CSRF verification failed.
This little Django app will prevent that specific error by converting
a POST request with the key signed_request to a GET request. Of course
this is just plain ugly, but Facebook should not mess with our
application.
Related
Forbidden (403)
CSRF verification failed. Request aborted.
You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.
If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.
More information is available with DEBUG=True.
In my django project when i deploy it to c panel its form submission giving me error i have already inclued the csrf token and also it is working perfectly fine during the development i did some research they were talking about the render function i have used redirect and i had to use
I've been using the Django admin panel for my project the entire time and suddenly after I cleaned my cookies it just won't work again it keep sending me this error:
Forbidden (403) CSRF verification failed. Request aborted.
Help:
Reason given for failure:
CSRF token missing or incorrect.
I am answering this question from the very less information available.
When you delete your cookies, the session-key stored on your browser side will be deleted. This way any API calls made after that will result in 403 error. Just to make sure this is correct, you can open your incognito tab in google chrome and try the same request after logging in.
Most of the SO answers are asking to clear cookies and confirm middleware class. I have already tried that.
Python - 3.4
Django - 1.10
Using VirtualEnv.
I am getting Forbidden (403) CSRF verification failed. Request aborted. error on Django admin login screen. I have hosted my site on pythonanywhere.com with django version 1.9.
I have cleared the browser cookies. All of them.
I reloaded the login screen. Get request.
In browser cookies, which were empty till now, one value has been set for my website, where csrf value is = XPp5hAhylAkt27U4SzGPNU7w8SFBJ3RP
In response header, set cookies was send with cookies value = UT24544MghHLZi0IrGHQlCcpk1v0SbCy . Same value was available in form's source code.
Now I entered the username and password and click on login button.
Received the 403 error CSRF verification failed. Request aborted.
I rechecked all the values of csrf token.
In request header CSRF cookies values = XPp5hAhylAkt27U4SzGPNU7w8SFBJ3RP
In form data csrf values = UT24544MghHLZi0IrGHQlCcpk1v0SbCy
I already have 'django.middleware.csrf.CsrfViewMiddleware', in middleware classes. I cleared browser cache and cookies. Even restarted the system.
I have used exactly same code on different site where it is working perfectly fine.
Why there are different csrf-token values? What is the solution to this problem?
update 1: If I set debug = False in settings, it works fine. But I cant keep it as code is live.
update 2: Upon further investigation I found out that somehow browser cookie csrftoken's value is not being set to correct value which is being passed in response header. If I delete and the cookie from browser and then set it to correct value from console, post requests work.
update 3 : Now same issue is happening with every post request or form submission I am doing on my web app. CSRF token value sent in response header and source code is not same as the one being set in browser cookies.
update 4: Setting CSRF_COOKIE_NAME = "csrf_token" also didn't helped.
The unexpected value for the CSRF token is set when the browser tries to fetch the favicon.
The URL you have defined for your favicon seems to be invalid, and apparently, non-existing URLs are handled by your default view. This sets a different CSRF cookie, but the page that is displayed in the browser still has the initial CSRF token in the form.
Request loading the page:
Request loading the favicon:
You can fix this particular error by ensuring that the favicon exists.
Note this this bug will come back whenever any resource you link (e.g. an image) does not exist because your app renders the homepage instead of returning a 404 error.
Setup
An angular application (~1.5) and django with django (1.9.9) rest framework (3.5.3) running on a server with nginx serving the client directly as static files from / and the api through uwsgi from /api
djangorestframework-jwt is in use to provide and validate the JWT tokens for the client.
Reproducing the error:
User logs into the client front end (angular app) successfully.
User clicks a link and GETs some data from the api.
User clicks to edit the data and changes form data and PUTs it to the api
All is well
User gots to /api and logs in via the DRF browsable API with same username and password
Goes back to / and tries to submit a form with PUT again.
Angular forwards the following error from the django server.
{"data":{"detail":"CSRF Failed: CSRF token missing or incorrect."},"status":403, JWT..., "statusText":"Forbidden"}
Finding the cause
Trying to narrow down the issue, I find that there is no csrf cookie nor session cookie found after logging in with the client app. I'm using JWT for authentication, so it shouldn't need any session.
The JWT token is being saved to local storage, not cookies.
After logging into the /api or /administration applications which are handled by django without angular at all, a csrftoken cookie and session cookie are set for that domain.
If I delete the csrf cookie, the angular app still can't PUT or POST. But if I delete the session cookie, it starts to work properly again.
Question
How should I be setting up the Django and/or Angular apps so that the user can login to either one without causing conflict?
Things I've considered
If users don't login to the backend app at all, there is no problem for them. But some will need to occasionally.
If I cause the session cookie to be deleted by Angular, the user will be logged out of the Django app, causing frustration if they need to have both open.
Solution
In working on clarifying this well enough to write a SO post, I've found a solution. Essentially, change Django settings to authenticate against the JWT first, so it never tries to check the session.
See below for more detail.
Since Django tends to process settings in the order they are listed, I tried moving the JSONWebTokenAuthentication line to the top of the list instead of the bottom as it would normally be when following the example on the REST framework JWT Auth docs page.
This worked out. So instead of throwing away the question I was almost done with, I've posted it here for your reading enjoyment.
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
A misleading feature of this error is that the csrf token didn't seem to be the actual problem. It was the session token that angular was passing back because angular was being served from the same host as the API.
I use Django 1.4. I created 403.html file in the same directory as 404.html (404 error page works fine). Yes, I read this. Then I turn off cookies in my browser, try to login and see the default 403-error page, not mine 403.html page:
Forbidden (403)
CSRF verification failed. Request aborted.
More information is available with DEBUG=True.
I restarted Apache, but it doesnt help.
How to fix it? Thanks
This is not the default 403-error page. You are seeing this message because the CSRF middleware does not work when cookies are disabled.
Your custom 403 template has no effect because the CSRF middleware does not use the general 403 view, but the view defined by the setting CSRF_FAILURE_VIEW, which is defined in django.conf.global_settings as django.views.csrf.csrf_failure. As you can see in the source, the message you are seeing is hardcoded in the view.
You could create your own CSRF_FAILURE_VIEW, but that is probably not what you want. I suggest you leave everything as it is and just delete the cookies or use another browser to test as unauthenticated user.