Chris B.
Chris B.

Reputation: 1575

Django iframe load denied by xframe options even after view is set to @xframe_options_exempt

I have a django app where I want to embed one embed view as an iframe on any site. thought I had this configured correctly because I'm setting the view as @xframe_options_exempt, but I'm still getting an x-frame options err in Chrome and Firefox.

Chrome: Refused to display 'https://foo.com/embed/...' in a frame because it set 'X-Frame-Options' to 'deny'.

Firefox: Load denied by X-Frame-Options: 'https://foo.com/embed/...' does not allow framing

views.py

from django.shortcuts import render, get_object_or_404, redirect
from django.views.decorators.clickjacking import xframe_options_exempt

    @xframe_options_exempt
    def embed(request, bar_slug, slug):
        embed_object = get_object_or_404(foo, slug=slug)

        if embed_object.bar.slug != bar_slug:
           raise Http404

        embed_url = '{}{}'.format('https://foo.com/embed', embed_object.get_absolute_url())

        context = {
            'embed_object': embed_object,
            'embed_url': embed_url,
            'embed_url_encode': urlquote_plus(embed_url),
    }

        return render(request, 'causes/embed.html', context)

settings.py

MIDDLEWARE_CLASSES = [
    'djangosecure.middleware.SecurityMiddleware',
    'project.utils.middleware.SiteMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'project.utils.middleware.HoneypotMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

I assume djangosecure.middleware.SecurityMiddleware is enforcing 'X-Frame-Options' over @xframe_options_exempt. I would prefer to address this with a view-specific solution and not set X_FRAME_OPTIONS = 'ALLOW'. thanks

Upvotes: 0

Views: 1420

Answers (1)

Chris B.
Chris B.

Reputation: 1575

I got it to work by using two decorators for the embed view:

from djangosecure.decorators import frame_deny_exempt
from django.views.decorators.clickjacking import xframe_options_exempt

@xframe_options_exempt
@frame_deny_exempt
def embed(...)

I was missing the django-secure decorator.

https://django-secure.readthedocs.io/en/v0.1.1/middleware.html

Upvotes: 1

Related Questions