Cross-project iframe testing on localhost with different ports - django

I am relatively new to iFrame, and what I try to do is to load project A in an iframe that is in project B. Project A is running as a Django project on localhost:8000, and project B as a separate Django project on localhost:8001. Inside the project B, I have a Django template with the following content:
<iframe src="http://127.0.0.1:8000" height="500px" width="500px"></iframe>
The problem is that instead of seeing the content of project A home page, I see error message stating that:
127.0.0.1 refused to connect
Is there anything I am terribly missing?

This is the default Clickjacking Protection [Django docs] by Django kicking into action (Great for us!), but this is preventing you from loading the iframe in your other project. There are various options to solve this issue:
If you want all your pages from your project to be put inside an iframe then you can remove 'django.middleware.clickjacking.XFrameOptionsMiddleware' from your MIDDLEWARE settings:
MIDDLEWARE = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
]
If this is for only specific views you can use the xframe_options_exempt decorator:
from django.views.decorators.clickjacking import xframe_options_exempt
#xframe_options_exempt
def some_view(request):
...

Related

How to disable header " X-Frame-Options: deny "?

I created a website in Django that I deployed on heroku. I am trying to display this website from an html page using an iframe. However, when I load my html page, I get the error: gkwhelps.herokuapp.com refused the connection. And when inspecting the page I get the following message:Refused to display 'http://gkwhelps.herokuapp.com/' in a frame because it set 'X-Frame-Options' to 'deny'. To solve this problem, I modified my settings.py like this:
MIDDLEWARE = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
...
from django.http import HttpResponse
from django.views.decorators.clickjacking import xframe_options_exempt
#xframe_options_exempt
def ok_to_load_in_a_frame(request):
return HttpResponse("This page is safe to load in a frame on any site.")
and I updated my site. But despite this, I still get the same error when I reload my page. I don't know why yet I updated my site.
You can try the following for setting same origin xframe option
from django.views.decorators.clickjacking import xframe_options_sameorigin
#xframe_options_sameorigin
def ok_to_load_in_a_frame(request):
return HttpResponse("This page is safe to load in a frame on any site.")
If you want to set it for your whole app, you could try adding the below line in your settings.py file
X_FRAME_OPTIONS = 'SAMEORIGIN'

How to fix cors error when loading static file served by Django runserver

Relevant info : Django version 2.2
I have installed django-cors-headers and added it to enabled apps and added the middleware to middleware settings as first middleware.
I have also configured the settings:
INSTALLED_APPS = [
...
"corsheaders",
"rest_framework",
"django.contrib.admin",
...
]
MIDDLEWARE = [
...
"corsheaders.middleware.CorsMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
...
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
My setup has 2 projects running on different ports. Django server running on 8000 and my front-end running on 8080.
All API requests the front-end sends against back-end work just fine. But when I try to load one.js file served by the back-end project it fails with this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8000/static/myscript.js. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)
The way I load the script is by creating a new script element and add the URL http://127.0.0.1:8000/static/myscript.js as value for the src attribute on the script tag.
This error does not occur when I use a value like https://code.jquery.com/jquery-3.5.1.min.js instead of http://127.0.0.1:8000/static/myscript.js so it looks like there is some issue with static files being served by Django runserver, but what exactly and why is beyond me.
I know that there is a bunch of cors related issues like Django CORS on static asset, but they are not about my issue or have gone unanswered. Also, I noticed, that the requests going at static files bypass the cors middleware anyway, so perhaps I should be doing something else here instead?
Perhaps someone can help me out here?
Thanks
A slightly different approach based on Odif Yitsaeb's idea, however you don't need to remove staticfiles or mess with urlpatterns. Simply place the following code into your settings.py:
from django.contrib.staticfiles import handlers
# extend StaticFilesHandler to add "Access-Control-Allow-Origin" to every response
class CORSStaticFilesHandler(handlers.StaticFilesHandler):
def serve(self, request):
response = super().serve(request)
response['Access-Control-Allow-Origin'] = '*'
return response
# monkeypatch handlers to use our class instead of the original StaticFilesHandler
handlers.StaticFilesHandler = CORSStaticFilesHandler
Notes:
Don't use that in production (you shouldn't use devserver in production anyway)
The handler must be monkeypatched very early, before any requests are served. Placing the code in settings.py will do the trick
It looks like I have sort of found the answer:
What I did was I added INSTALLED_APPS.remove('django.contrib.staticfiles') into dev settings.
and I created view like
from django.contrib.staticfiles.views import serve
def cors_serve(request, path, insecure=False, **kwargs):
kwargs.pop('document_root')
response = serve(request, path, insecure=insecure, **kwargs)
response['Access-Control-Allow-Origin'] = '*'
return response
for serving static content. And I added it into urlconf like this:
from utils.views import cors_serve
...
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT, view=cors_serve)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT, view=cors_serve)
This does take care of the issue for me. I know that the Django docs (https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#runserver) suggest that you can skip static files serving with using runserver like this: django-admin runserver --nostatic but that had absolutely no effect for me if I still had "django.contrib.staticfiles" in my INSTALLED_APPS

How to show flatpages with a single URL in Django?

I am trying to namespace Flatpages in Django. I included /pages/ in URLConf and added one URL /help/ in Django Admin Sites module. However, the page is loading with '/help/' and '/pages/help/' both URLs. I am trying to stop this behaviour and only load the page with /pages/help/. How is this possible?
urlpatterns = [
...
url(r'^pages/', include('django.contrib.flatpages.urls')),
]
You must have the fallback middleware installed in your MIDDLEWARE_CLASSES setting:
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'
Remove it, and then it will only work on the prefix you have specified.

Change header 'Django administration' text on nginx

I followed this question's answers to change my django admin panel title header.
I tried this:
There is an easy way to set admin site header - assign it to current
admin instance in urls.py like this
admin.site.site_header = 'My admin'
But it just works when I'm running the page via Python manage.py runserver
My question is how can I change the admin title header when I'm running the site via gunicorn and nginx
writing this code at the bottom of urls.py somehow worked:
admin.site.site_header = 'My admin'
If you already have an admin.py file started wherein you have registered your particular models, you can simply adjust these values there.
your_app/admin.py
# Simple admin setup
from django.contrib import admin
from .models import MyModel
# Register model
admin.site.register(MyModel)
# Tweak admin site settings like title, header, 'View Site' URL, etc
admin.site.site_title = 'My App Admin'
admin.site.site_header = 'My App Admin'
You can find all the attributes here.
follow the below steps to customize the site header and site title text of django admin login page :
1.)First import admin module in settings.py file like as below :
from django.contrib import admin
2.)In bottom of settings.py file add these lines:
admin.site.site_header = 'MY_SITE_HEADER'
admin.site.site_title = 'MY_SITE_TITLE'
The above method works in latest version of django i.e.1.11.3 till date.
You can make changes to parts of the admin by providing a template in an admin subdir of your templates directory to override what is provided by admin.
In this case, you'd want to provide a base_site.html template. You can see what the default one looks like here: https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/base_site.html

Is it possible to include a custom 404 view for a Django app without changing anything at the project level?

I'm creating a Django app and trying to have it touch the containing project in as few places as possible.
I've created a custom 404 view which works as expected but only when I add handler404 to the project-level urls.py.
I want the custom 404 view that I've written to apply to this particular app only, but from the information I've come across it appears that this may not be possible. Adding handler404 to the app-level urls.py does not have any effect.
Does Django support custom 404 views at the application level?
Instead of finishing your view with:
return render_to_response(...)
Get the response object and check its status:
out = render_to_response(...)
if out.status_code==404:
# redirect to your 404 page
else:
return out