【Django】Refused to display(X-Frame-Options to deny)エラーの解決方法

時計 2020.11.29 / 時計

【Django】Refused to display(X-Frame-Options to deny)エラーの解決方法

DjangoアプリケーションでPDFを表示するためにobjectタグを使用した際に、エラーが発生してPDF表示がうまくできなかったことがあります。

これはHTTPレスポンスヘッダーのX-Frame-Optionsが起因しています。

objectタグだけでなく、frameタグ・iframeタグでも同様のエラーが発生し、画像やPDFの表示ができないことがあります。

本記事では、DjangoアプリケーションにおいてRefused to display(X-Frame-Options to deny)エラーが表示した際の解決方法について解説していきます。

エラー内容

Djangoアプリケーションでobjectタグやiframeタグを使用すると、画像やPDFは表示されない場合があります。
その際にブラウザの開発ツールを起動すると以下のようなエラーが表示しています。

Refused to display '画像URL' in a frame because it set 'X-Frame-Options' to 'deny'

上記エラーは、「フレーム内の画像表示は拒否されました、なぜならX-Frame-Optionsが拒否に設定されているからです」と記載されています。

まずはX-Frame-Optionsとは何か、そしてこのエラーを解決する方法を解説します。

X-Frame-Options

X-Frame-Optionsとは

X-Frame-OptionsとはWebサーバーが送信するHTTPレスポンスヘッダーの1つの項目です。
これは外部サイトのフレーム(<frame>, <iframe>, <embed>, <object>)に、管理するサイトページが表示されるのを許可するかどうかを設定することができます。

ブラウザーはWebサイトのページをフレーム上に表示する際に、Webサーバーから送信されるHTTPレスポンスヘッダー内のX-Frame-Optionsから表示の可否を判断しています。

このX-Frame-Optionsはクリックジャッキングと呼ばれる悪意ある攻撃からユーザーを守るための技術です。

クリックジャッキングとは

悪意のあるサイトの上にフレームで別サイトを表示し、ユーザーが意図していないボタンやリンクを押させる手法

指定できる値

X-Frame-Optionsに指定できる値を以下に示します。

説明
DENY フレーム上に表示させることを拒否(同じサイト内でも拒否)
SAMEORIGIN 同じサイト内のみフレーム上に表示させることを許可
ALLOW-FROM URL 指定するURLのみ表示させることを許可

基本的にはクリックジャッキングを防ぐために値はDENYにします。
同じドメイン内でどうしてもフレーム(<frame>, <iframe>, <embed>, <object>)を表示する場合はSAMEORIGINを使います。

ALLOW-FROMはすでに廃止されており、最新のブラウザーでは動作しないこともありますので、使わないようにしましょう。

Refused to displayエラーの解決方法

X-Frame-Optionsはsettings.pyのX_FRAME_OPTIONSで設定します。
Django3.0からはX_FRAME_OPTIONSのデフォルト値が変更になりました。

Django3.0以前のデフォルトはX_FRAME_OPTIONS="SAMEORIGIN"でした。
それがセキュリティ強化により、X_FRAME_OPTIONS="DENY"がデフォルト値となりました。

そのためサイトでiframeなどを埋め込んでいる場合は、この設定を変更する必要があります。
変更しないと「Refused to display」のエラーが発生します。

Djangoアプリケーションで、Refused to display(X-Frame-Options to deny)エラーが発生した場合は、settings.pyに以下2文を追記してX-Frame-Optionsを変更しましょう。

X_FRAME_OPTIONS = 'SAMEORIGIN'

XS_SHARING_ALLOWED_METHODS = ['POST','GET','OPTIONS', 'PUT', 'DELETE']

上記2文を追記することで、Djangoアプリは同じサイト内であればフレーム(<frame>, <iframe>, <embed>, <object>)への表示を許可します。

まとめ

DjangoアプリでのRefused to display(X-Frame-Options to deny)エラーが表示した際の解決方法はいかがでしたか。

今回はHTTPレスポンスヘッダーが問題解決のカギでしたね。

今回紹介したX-Frame-Optionsやクリックジャッキングという言葉はWeb製作者なら知っておくべき知識なので忘れないようにしましょう。