Django_hosts Not Working With Django's Default Authentication - python

I'm using this package called django_hosts to re-route urls for some apps.
Everything is working fine except for the fact that django_hosts is not working with Django Authentication.
I hosted this url api.example.com, so on this page with the url api.example.com:8000/add_post, I want users to add post but before doing that you must be authenticated. So after I logged in, I still can't submit post via the form talkless of posting. But when I go back to example.com, it shows that I'm logged in but api.example.com is telling me otherwise.
How do I make django authentication work with this package?

The problem is that the authentication token is hooked to the domain. Using Django's default configuration, the api.example.com can't access the example.com auth token.
You can change this behaviour by setting the SESSION_COOKIE_DOMAIN configuration in your settings.py module:
SESSION_COOKIE_DOMAIN = 'example.com'
But not too fast! Do it carefully, otherwise you can break your application:
Be cautious when updating this setting on a production site. If you
update this setting to enable cross-domain cookies on a site that
previously used standard domain cookies, existing user cookies will be
set to the old domain. This may result in them being unable to log in
as long as these cookies persist.
More info on the official documentation.

Related

Unable to Login Django Admin after Update : Giving Error Forbidden (403) CSRF verification failed

I am encountering the error Forbidden (403) CSRF verification failed when trying to login into the Django Admin after updating the version of Django.
Also, there were no changes in the settings of Django.
The error can be seen in the below image:
I Already posted it on https://shriekdj.hashnode.dev/unable-to-login-django-admin-after-update-giving-error-forbidden-403-csrf-verification-failed-request-aborted.
This Issue can happen suddenly after updating to the newer version Of Django.
Details
Django Project Foundation team made some changes in security requirements for all Django Versions 4.0 and Above. They made it mandatory to create a list of URLs getting any type of form upload or POST request in project settings named as CSRF_TRUSTED_ORIGINS.
They did not update the details in the latest tutorial documentation, but they published the Changes Notes at https://docs.djangoproject.com/en/4.0/releases/4.0/#csrf-trusted-origins-changes-4-0.
First Solution
For localhost or 127.0.0.1.
Goto settings.py of your Django project and create a new list of URLs at last like given below
CSRF_TRUSTED_ORIGINS = ['http://*', 'https://*']
if You're running a project in localhost, then you should open all URLs here * symbol means all URLs. Also, http:// is mandatory.
Second Solution
This is also for Localhost and DEBUG=True.
Copy the list of ALLOWED_ORIGINS into CSRF_TRUSTED_ORIGINS as given below.
ALLOWED_ORIGINS = ['http://*', 'https://*']
CSRF_TRUSTED_ORIGINS = ALLOWED_ORIGINS.copy()
Third Solution
When deploying, you have to add URLs to allow form uploading ( making any POST request ).
I know this may be tricky and time-consuming but it's now mandatory.
Also, this is mandatory for Online IDEs also like Replit and Glitch.
Open the config file (most likely settings.py) and set the CSRF_TRUSTED_ORIGINS key as a shallow copy of the ALLOWED_HOSTS key which, in turn, should be set as recommended in the documentation.1
For example:
# -*- coding: utf-8 -*-
# For security consideration, please set to match the host/domain of your site, e.g., ALLOWED_HOSTS = ['.example.com'].
# Please refer https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts for details.
ALLOWED_HOSTS = ['.yourdomain.com', '.localhost', '127.0.0.1', '[::1]']
# Whether to use a secure cookie for the CSRF cookie
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-secure
CSRF_COOKIE_SECURE = True
# The value of the SameSite flag on the CSRF cookie
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-samesite
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS.copy()
(...)
1 The config file contains a link to the documentation of the ALLOWED_HOSTS key — right above that key. Surprise, surprise.

How to fetch a csrftoken from a django server?

I'm reconfiguring my CDN and I want to begin caching pages that use csrf tokens for form submission. Currently, I'm submitting the csrf token with javascript in a post request with:
axios.defaults.headers.post['X-CSRFToken'] = getCookie('csrftoken')
This works pretty well locally and allowed me to remove the csrf tokens from the templates.
This obviously will not work if I'm accessing cached pages from the CDN. So is it possible for me to fetch a csrf token from the server using Axios and subsequently set it in a post request? If so how do I do this?
An alternative approach would be to disable csrf which I tried already but I couldn't fully disable it. If you are signed into admin csrf protection is automatically enabled even on your frontend forms, I couldn't figure out how to remove this not sure if it's a wagtail or django thing.
I'm using Django 2.2 + Wagtail 2.11.

How to include Django CSRF token in request through ngrok?

I am building a Django app that will be hosted on a local network and perform authentication using Facebook Login. Since Facebook Login requires the callback address for a login to either be localhost or publicly-addressable, I'm using ngrok to create an address for Facebook to return data to.
After the user logs in with Facebook, I perform a POST with AJAX from the template with their data to a local view (/fb_login) which saves to my database in Django. Since authentication is based on this database, I don't think it's wise to avoid the CSRF checks Django performs on this view.
To include the CSRF token in the POST to /fb_login, I'm using the following which a few forums suggested:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
This should only include the CSRF token to relative URLs (which I understand to be the best practice). When I run the server on localhost and perform the Facebook Login from the same machine, this works fine. However, when I run the system on localhost and access it through ngrok from another machine on the local network and perform the Facebook Login, I get a 403 and a message saying the CSRF check failed. This leads me to believe that the ngrok URL isn't considered "local", so the CSRF token isn't being set.
Assuming I know what my ngrok URL is at the time my Django server starts, can I include it in what's considered a "local" address for the purposes of including the CSRF token? Is there another way to do this securely? As a note, web development is not my area, so please let me know if I'm misunderstanding something here. Thanks!

django admin returns 403 csrf error

I am producing a django/angular project. Django being the backend administration and Angular being the frontend/public display. I have created a Django 1.11 app and loaded all files, installed dependencies, etc. Locally, the site works fine and as expected. Also, since forms will be Angular js I commented out the django.middleware.csrf.CsrfViewMiddleware in my settings.py which I thought would disable the csrf token even being needed, but apparently not.
After setting up server and installing files the admin login page appears but I get the following error when I try and login:
Forbidden (CSRF token missing or incorrect.): /admin/login/
Any ideas on why this is happening would be greatly appreciated.
You can't commented out the 'django.middleware.csrf.CsrfViewMiddleware' in your settings.py, The CSRF middleware provides easy-to-use protection against Cross Site Request Forgeries. Since you are using Augualr js instead of django forms and views, you can set the csrftoken cookie in your browser cookies. Check this for detail: https://docs.djangoproject.com/en/1.11/ref/csrf/#module-django.middleware.csrf

How to make facebook app allow requests from django project that runs on a local server?

I am trying to use django social auth to auth via facebook.
I used this documentation to make changes in my django project and to create and setup the facebook app. I am running django project on local server. The project has url http://127.0.0.1:8000. When hit the following link on my project's web page:
Template
<p>Facebook</p>
Rendered template
<p>Facebook</p>
it redirects me to a facebook page where I can see the following message:
Given URL is not allowed by the Application configuration: One or more
of the given URLs is not allowed by the App's settings. It must match
the Website URL or Canvas URL, or the domain must be a subdomain of
one of the App's domains.
How to change facebook app's settings to allow
http://127.0.0.1:8000?
upd
Added localhost to app domains and http://localhost:8000/ to site URL in my fb app's settings.
The Facebook app doesn't allow IP addresses like that, but it does allow localhost. In the App Domains on the Settings tab you need to add localhost. What sucks is that other services (such as twitter) don't accept localhost and you can only use 127.0.0.1:8000, which means you have to switch back and forth.
It works for local development, but it's not pretty.
EDIT:
You also need to add http://localhost:8000/ to the Site URL first

Categories

Resources