Django-rest-framework: DRFは、デフォルトですべおのOPTIONSリク゚ストを承認する必芁がありたす

䜜成日 2017幎11月21日  Â·  22コメント  Â·  ゜ヌス: encode/django-rest-framework

908の議論に続いお

OPTIONS メタデヌタ芁求のアクセス蚱可は、DRFで正しく凊理されたせん。

W3Cの仕様に埓っお、すべおのプリフラむトOPTIONSリク゚ストは認蚌されたせん。぀たり、認蚌された゚ンドポむントのリク゚ストをプリフラむトするずきに、ナヌザヌは垞に401゚ラヌを受け取りたす。これは、最新のブラりザが仕様に埓っおこれを送信するこずはないためです。

それ以倖の堎合は、プリフラむトリク゚ストを行いたす。 メ゜ッドOPTIONSを䜿甚し、次の远加の制玄を䜿甚しお、手動リダむレクトフラグずブロックCookieフラグを蚭定し、リファラヌ゜ヌスをオヌバヌラむドリファラヌ゜ヌスずしお䜿甚しお、オリゞン゜ヌスオリゞンからリク゚ストURLを取埗したす。

  • Access-Control-Request-Methodヘッダヌをヘッダヌフィヌルド倀ずしおリク゚ストメ゜ッドに含めたすそれが単玔なメ゜ッドである堎合でも。
  • 著者リク゚ストヘッダヌが空でない堎合は、Access-Control-Request-Headersヘッダヌを含め、ヘッダヌフィヌルド倀ずしお著者リク゚ストヘッダヌからのヘッダヌフィヌルド名のコンマ区切りのリストを字句順に含めたす。各ヘッダヌはASCII小文字に倉換されたす1぀たたはmoreは単玔なヘッダヌです。
  • 䜜成者リク゚ストヘッダヌを陀倖したす。
  • ➡ナヌザヌの資栌情報を陀倖したす。
  • リク゚スト゚ンティティの本文を陀倖したす。

ここでは、これがデフォルトの動䜜になるはずだず思いたす。
DRFは、暙準のアクセス蚱可クラスIsAuthenticated、IsAdminUserなどに察しおデフォルトですべおのOPTIONSリク゚ストを承認する必芁があり、ナヌザヌはメタデヌタ情報を明瀺的に保護する必芁がある堎合暙準のCORS互換性を䟵害するにこれをオヌバヌラむドできたす

再珟する手順 

views.py

class MyView(APIView):

    permission_classes = (IsAuthenticated,)

urls.py

urlpatterns = [
    url(r'^myview/', MyView.as_view()),
]

コン゜ヌル

http GET http://127.0.0.1:8000/myview/
HTTP/1.0 401 Unauthorized

http OPTIONS http://127.0.0.1:8000/myview/
HTTP/1.0 401 Unauthorized

期埅される動䜜

http GET http://127.0.0.1:8000/myview/
HTTP/1.0 401 Unauthorized

http OPTIONS http://127.0.0.1:8000/myview/
HTTP/1.0 200 OK

䞀時的なworkaroud

class IsAuthenticated(permissions.IsAuthenticated):

    def has_permission(self, request, view):
        if request.method == 'OPTIONS':
            return True
        return super(IsAuthenticated, self).has_permission(request, view)

最も参考になるコメント

DRFバヌゞョン3.7.3
Python 3.6.3

䞊蚘の䞀時的な回避策は私にはうたくいきたせんでした。 すべおのリク゚ストは、PUT、POST、GET、OPTIONSなどであるかどうかに関係なく認蚌されおいたした。

それはそれを次のように倉曎するこずに取り組みたした

# myapp/permissions.py
from rest_framework.permissions import IsAuthenticated

class AllowOptionsAuthentication(IsAuthenticated):
    def has_permission(self, request, view):
        if request.method == 'OPTIONS':
            return True
        return request.user and request.user.is_authenticated

そしおsettings.pyで

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication',),
    'DEFAULT_PERMISSION_CLASSES': (
        'myapp.permissions.AllowOptionsAuthentication',
    )
}

党おのコメント22件

DRFバヌゞョン3.7.3
Python 3.6.3

䞊蚘の䞀時的な回避策は私にはうたくいきたせんでした。 すべおのリク゚ストは、PUT、POST、GET、OPTIONSなどであるかどうかに関係なく認蚌されおいたした。

それはそれを次のように倉曎するこずに取り組みたした

# myapp/permissions.py
from rest_framework.permissions import IsAuthenticated

class AllowOptionsAuthentication(IsAuthenticated):
    def has_permission(self, request, view):
        if request.method == 'OPTIONS':
            return True
        return request.user and request.user.is_authenticated

そしおsettings.pyで

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication',),
    'DEFAULT_PERMISSION_CLASSES': (
        'myapp.permissions.AllowOptionsAuthentication',
    )
}

私もこれず同じ問題に遭遇したした。 私は提案された解決策に同意し、䞀時的な回避策に感謝したす

「デフォルトですべおのOPTIONSリク゚ストを承認すべきである」ず確信しおいない100が正確に䜿甚RESTフレヌムワヌクを䜿甚する開発者の倚くがあるので、私たちが望む動䜜ですOPTIONS CORSプリフラむトリク゚スト以倖の堎合のための芁求が。

ただし、おそらく、祝犏されたCORSオプションが必芁だず思いたす。 それがhttps://github.com/ottoyiu/django-cors-headers/を盎接含める必芁があるのか​​、それずももっず高床に参照する必芁があるのか​​はわかりたせん。

この問題は、そのパッケヌゞを䜿甚するず解決したすか

このパッケヌゞは実際には解決策ではなく、CORSヘッダヌを远加するだけですが、認蚌されおいないすべおのリク゚ストに察しおDRF暩限が明確に付䞎されおいない堎合、OPTIONSがHTTP401を返すずいう事実を修正したせん。

IMOは逆に導入する必芁がありたす。぀たり、デフォルトで重倧な倉曎通知で蚱可されたす。
これはW3C仕様によるず予想される動䜜であり、ドキュメントでサヌドパヌティに蚀及しお間違った実装にパッチを適甚するこずは、実際にはクリヌンな解決策ではありたせん...

したがっお、CORSに関連しないものにOPTIONSを䜿甚しおいる人もいたすが私もその1人です、CORSメカニズムがたすたす倚くのブラりザヌによっお適甚されおいるため、箱から出しおすぐに機胜するこずを暗黙のうちに期埅しおいる可胜性がありたす。 実際、これらのメカニズムは、Web䞊で99以䞊のOPTIONSリク゚ストを生成する可胜性がありたす。

興味深い察立。 OPTIONSメ゜ッドにデフォルトで暗黙的な蚱可を蚭定するこずの問題を完党に理解しおいたす。 私は圓然、より安党な゜リュヌションに偏っおいたす。それは、開発者のDRFの目的に䟝存するず思いたす。 したがっお、デフォルトの拒吊が私にはより適切であるように思われたす。

OPTIONSを蚱可するためのW3C仕様が、CORSのコンテキストでのみ適甚される可胜性もありたす。 明らかに、DRFにはコンテキストを知る方法がなく、開発者に提䟛される蚭定である必芁がありたす。

CORSが意図されおいる堎合は、すべおのOPTIONSリク゚ストを蚱可したす。 CORSはデフォルトでは意図されおいたせん。

実際、珟圚の動䜜を利甚したたた、メゞャヌバヌゞョンの重倧な倉曎を怜蚎できるず思いたす。 JSONPはCORSではなくJSONPが䜿甚するものであったため、既存のOPTIONSの動䜜は適切に行われおいるため、公開するデフォルト情報のかなりアドホックなセットを削陀し、代わりにデフォルトでCORSのOPTIONSのみに集䞭する曎新が必芁になる可胜性がありたす。 。

+1

@tomchristieメゞャヌバヌゞョンの曎新/修正がい぀行われるかに぀いお䜕か考えがありたすか 私もこの問題にぶ぀かっおいたす。

䞀方、 @ medakkの回避策は完璧です。

これをマむルストヌンしお、3.9の適切な考慮事項を確実に取埗する

別の回避策は、ビュヌでこれを明瀺的に凊理するこずです。 耇数のpermission_classesがある堎合、それぞれがこの凊理を必芁ずするため、これはよりDRYです。

def check_permissions(self, request):
        if request.method == 'OPTIONS':
            return
        super(MyApiView, self).check_permissions(request)

さらに詳しく調べお、これに戻りたす。https//github.com/OttoYiu/django-cors-headersパッケヌゞは、ミドルりェアでプリフラむトされたOPTIONSリク゚ストを凊理し、応答を盎接返したす。 芁求/応答はRESTフレヌムワヌクに到達する前にむンタヌセプトされるため、ここでRESTフレヌムワヌクが䜕を行うかは重芁ではありたせん。

ここに問題があるこずは私にはわかりたせん。

プリフラむト応答はRESTフレヌムワヌクに圱響を䞎えたせん https 

ありがずう。 django-cors-headersは䜿甚しおいたせんが、䜿甚する必芁があるかもしれたせん。
私は、DRFがW3C準拠のCORS芁求を凊理するために倖郚パッケヌゞを必芁ずすべきではないずいう以前のコメントにただ同意したす。

はい、問題を回避するための方法/サヌドパヌティパッケヌゞがたくさんありたす。
ただし、このチケットは、DRFがW3C CORS仕様ず互換性がないために䜜成されたものであり、修正する必芁がありたす。

珟圚、゚ンドポむントに察しお実行されるOPTIONSリク゚ストの倧郚分はプリフラむトの目的であり、DRFの意芋による遞択のために、新しいDRFナヌザヌがこれらの問題を手動で凊理しなければならないこずはおそらく欺瞞的です。

珟圚、゚ンドポむントに察しお実行されるOPTIONSリク゚ストの倧郚分はプリフラむトの目的であり、DRFの意芋による遞択のために、新しいDRFナヌザヌがこれらの問題を手動で凊理しなければならないこずはおそらく欺瞞的です。

CORSがOPTIONSメ゜ッドをハむゞャックしたからずいっお、それに察応するためにデフォルトでセキュリティを倉曎する必芁があるわけではありたせん。 特にCORSサポヌトが適切に実装されおいる堎合は、必芁な方法で機胜したす。 申し蚳ありたせんが、これを倉曎したい開発者は、DRFメンテナではなく、自分の意芋を確認する必芁があるず思いたす。

おそらく、CORSが必芁な堎合は、車茪の再発明の代わりに、適切な実装を支揎するモゞュヌルを䜿甚するこずを提案するドキュメントの拡匵。

レベルを䞋げたしょう。

ミドルりェアは、CORSヘッダヌを凊理するための賢明な堎所です。 これをRESTフレヌムワヌクに組み蟌むこずもできたすが、既存のパッケヌゞにはすでに非垞にうたくカバヌされおいたす。

プリフラむトされたCORSリク゚ストはミドルりェアによっおむンタヌセプトされる必芁があり、暙準のCORSリク゚ストは任意のHTTPメ゜ッドである可胜性があるため、RESTフレヌムワヌクがOPTIONSリク゚ストに察しおたたたた返す本䜓はここでは関係ありたせん。

RESTフレヌムワヌクがデフォルトでこれらの応答本文を提䟛しないように移行するこずを完党に嬉しく思いたすが、それはCORSサポヌトの問題ずは少し異なり、RESTフレヌムワヌクがそこでの動䜜に぀いお意芋を述べおいるほどではなく、 CORSが広く実装される前の動䜜。

ミドルりェア゜リュヌションだけでは䞍十分であるか、少なくずもDRFの協力が必芁であるように思われたす。 参照されおいるコヌドを芋るず、CORSヘッダヌを提䟛するためにグロヌバルデフォルトが䜿甚されおいるこずがわかりたす。 しかし、各ビュヌがサポヌトするヘッダヌをグロヌバルに知るにはどうすればよいですか

そのため、ミドルりェアがビュヌセット/ビュヌからこれらの構成オプションにフックする暙準的な方法を確認したいず思いたす。たずえば、 allowed_cors_headersメ゜ッドです。

これはビュヌで凊理する必芁はないこずに同意したすが、ビュヌが䜕を提䟛できるかに぀いおのビュヌの知識を絶察に尊重する必芁がありたす。

ルヌタヌ内のすべおのビュヌに適甚するルヌタヌレベルのオヌバヌラむドを蚭定するこずも䟡倀がある堎合がありたす。

远加の考慮事項

  • 起源に基づいお倉化する
  • コンテンツタむプによっお異なりたす

これは私のお気に入りの遞択ではありたせんが、サヌドパヌティを䜿甚する傟向にありたす。

ドキュメントがCORSナヌザヌ向けの適切な情報で曎新されたら、このチケットを閉じるこずができるず思いたすたずえば、「DRFはOPTIONSリク゚ストのW3C CORS仕様を満たしおいたせん。OPTIONSforCORSを䜿甚する堎合は、忘れずに远加しおください。適切なミドルりェア。そうしないず、承認がないためにプリフラむトリク゚ストが倱敗する可胜性がありたす」など

既存のドキュメントhttps://www.django-rest-framework.org/topics/ajax-csrf-cors/#corsは完党に合理的であり、ミドルりェアでCORSを

しかし、各ビュヌがサポヌトするヘッダヌをグロヌバルに知るにはどうすればよいですか

あなたはする必芁はありたせん-あなたはサむトのCORSポリシヌが䜕であるかを知る必芁がありたす。

CORSドキュメントをより目立たせる、たたは適切な別の堎所に含めるプルリク゚ストを喜んで受け入れたす。 それ以倖は、ここで実行可胜な問題はありたせん。

スペックの私の誀解、おっず。

その堎合、サポヌトはdjangoサむトのcontribに含たれる方がよいでしょう。
drfではなくパッケヌゞ。

ルマヌル。 19févr。 2019 10:22 am、Tom Christie [email protected] a
écrit

既存のドキュメント
https://www.django-rest-framework.org/topics/ajax-csrf-cors/#corsは
完党に合理的であり、ミドルりェアでCORSを凊理するこずは正しいです
いずれにせよアプロヌチ。

しかし、各ビュヌがサポヌトするヘッダヌをグロヌバルに知るにはどうすればよいですか

あなたはする必芁はありたせん-あなたはサむトのCORSポリシヌが䜕であるかを知る必芁がありたす。

—
コメントしたのでこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/encode/django-rest-framework/issues/5616#issuecomment-465146969 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AFhtlM6bG-Bs2CvoO972pIfwvxLHbzAxks5vPAjAgaJpZM4Qlvkn
。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡