50

I was logging into my django admin console easily a few minutes ago. I must have changed something somewhere that caused this error when logging in as superuser:

Forbidden (403) CSRF verification failed. Request aborted.

This error caught me off guard as I was logging in all night. Why would I suddenly need a csrf token for admin login? You would think the sign in form already has that. This is my admin.py:

from django.contrib import admin
from accounts.models import Image, Category, UserProfile

class ImageAdmin(admin.ModelAdmin):
    list_display    = ["__unicode__", "title", "created"]

admin.site.register(Image, GenericImageAdmin)

class CategoryAdmin(admin.ModelAdmin):
    list_display    = ["category"]

admin.site.register(Category, CategoryAdmin)

admin.site.register(UserProfile)
mishbah
  • 5,487
  • 5
  • 25
  • 35
codyc4321
  • 9,014
  • 22
  • 92
  • 165
  • I cleared the database w flush, and now my app is working and I can make new users and whatnot. But I cannot use the admin. If I do "createsuperuser" I get an admin user and it complains that user does not have a userprofile. This is true, making a superuser doesn't make userprofile- userprofile is made when I make a new fake user in my registration page – codyc4321 Apr 11 '15 at 02:01
  • from django.db import models from django.contrib.auth.models import User class UserProfile(models.Model): user = models.OneToOneField(User) blurb = models.CharField(max_length=800, default='') def __unicode__(self): return self.user.username – codyc4321 Apr 11 '15 at 02:01
  • it wont let me make it look like code – codyc4321 Apr 11 '15 at 02:03
  • My apologies for the snark. I didn't expect the question asker to be adding code in comments (edit your question instead). For future reference, surrounding with backticks (`) indicates code in-line (both in comments and posts) – Basic Apr 11 '15 at 03:25
  • @Basic you're fine, I'm complete SO noob. Any snark was deserved haha – codyc4321 Apr 11 '15 at 21:17

9 Answers9

86

for new users facing this issue after upgrading to Django +4.0 you need to add CSRF_TRUSTED_ORIGINS=['https://*.YOUR_DOMAIN.COM'] to settings.py

thanks to the below answer:

https://stackoverflow.com/a/70326426/2259546

Zeedia
  • 1,313
  • 14
  • 20
45

Admin login normally does require a csrf token, but that's normally all taken care for you.

  1. Check your browser's cookies to see if there is a csrf token present
  2. Try clearing cookies and refreshing
  3. If you are using Django 4.0, you may to add this line to your settings.py file: CSRF_TRUSTED_ORIGINS = ['https://*.mydomain.com','https://*.127.0.0.1'] (making the appropriate changes). In 4.0, they started checking the origin header unlike in previous versions. Thanks to this answer for suggesting this solution.
  4. Check to make sure you have django.middleware.csrf.CsrfViewMiddleware in your middleware
  5. Check that you're either on https or you have CSRF_COOKIE_SECURE=False (which is the default) in settings, otherwise your csrf cookie exists but won't be sent. Purge your cookies after changing CSRF_COOKIE_SECURE.
ubadub
  • 3,571
  • 21
  • 32
  • so after debugging an issue not anywhere near related to django.admin, it works again. Wish I could add insight for other django noobs, but the only thing I did was manually add UserProfiles (connected like usual) to my users from createsuperuser `class UserProfile(models.Model): user = models.OneToOneField(User)` – codyc4321 Apr 11 '15 at 21:18
  • I have a registration page where new users sign up and are forced to make userprofile from the registration form, now when I make create super user from manage.py command is there a prettier pythony way to give them a blank userprofile instead of manually doing it in shell then hitting save()? It seems very 1995 what I'm doing – codyc4321 Apr 11 '15 at 21:21
  • Assuming you have a standard userprofile defined in settings.py, it should be auto-created when you do create super user, if memory serves. – ubadub Apr 12 '15 at 08:49
  • 4
    @ubadub added another reason to your list, hope you don't mind (`CSRF_COOKIE_SECURE = False`). – Mark Feb 01 '16 at 21:20
  • Yes, I am on https. And now? – Soerendip Oct 18 '19 at 00:27
  • 1. There was. So, I removed it. 2. Did that. 3. Yes. 4. My code does not explicitly set CSRF_COOKIE_SECURE. Tried setting it to False explicitly. No change. – BogeyMan Apr 22 '20 at 02:38
  • i'm using django 4.0 and for me adding ```CSRF_TRUSTED_ORIGINS = ['https://*.mydomain.com']``` in `settings.py` works for me – Jackson Jegatheesan Jun 12 '23 at 20:59
5

This error was appearing for me when I had not set CSRF_COOKIE_DOMAIN in my settings_local but it was set in my main settings.py.

In my case I set it to the local host eg

CSRF_COOKIE_DOMAIN = '127.0.0.1'
jowan sebastian
  • 253
  • 2
  • 11
3

Add a csrf token to your context in the login view and in your template add in the hidden div for the csrf token. Ensure you have django.middleware.csrf.CsrfViewMiddleware in the middleware section in your settings.py.

Then add @csrf_protect to your views to do with login. It is also possible you tried to login with incorrect credentials - you need @csrf_protect on the logout view in your app's views.py you call on the appropriate uri for login/logout etc. in urls.py also. My logout simply calls logout(request) then calls HttpResponseRedirect('') which is probably not perfect but it does me for my needs for now.

Rodent
  • 1,698
  • 1
  • 12
  • 13
3

As a security measure, I had CSRF_COOKIE_SECURE = True in my settings. Trying to log into admin via localhost where there isn't HTTPS threw the forbidden error.

Set it to False to get it working on localhost

KhoPhi
  • 9,660
  • 17
  • 77
  • 128
1

This could also happen when you are already logged in into your website hosted on a url different than admin. And then try to login into your admin panel in a new tab. Try to open the admin panel in a different window.

r4v1
  • 355
  • 2
  • 8
1

In my case it was solved by changing the setting:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

to

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'http')
Piero
  • 1,583
  • 10
  • 12
0

Try opening your site in incognito mode.

There is a good chance that it could be your browser cookie, the above test will iron out that possibility.

-1

I used to have the same problem every time when I was using my default environment, and then using a virtual environment worked for me. It works every time. If you don't know how to create a virtual environment, here's how you do it:

  1. Just create a virtual environment in your project's directory by running the command virtualenv theNameYouWannaGiveYourEnvironment.
  2. Then activate your virtual environment by using theNameYouWannaGiveYourEnvironment/bin/activate(on Linux, I think it works for Mac Os too, but it's different for Windows).
  3. After that, just install Django by pip install django and all the other requirements for your application to run.

Alternatively, you can also use Anaconda to create your virtual environment and install all your requirements. Just refer to this documentation if you wanna use anaconda: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html

Suraj S Jain
  • 515
  • 3
  • 10
  • 24