ïŒ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
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',
)
}
ç§ããããšåãåé¡ã«ééããŸããã ç§ã¯ææ¡ããã解決çã«åæããäžæçãªåé¿çã«æè¬ããŸãïŒ
ãããã©ã«ãã§ãã¹ãŠã®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
ã
æãåèã«ãªãã³ã¡ã³ã
DRFããŒãžã§ã³ïŒ3.7.3
Python 3.6.3
äžèšã®äžæçãªåé¿çã¯ç§ã«ã¯ããŸããããŸããã§ããã ãã¹ãŠã®ãªã¯ãšã¹ãã¯ãPUTãPOSTãGETãOPTIONSãªã©ã§ãããã©ããã«é¢ä¿ãªãèªèšŒãããŠããŸããã
ããã¯ããã次ã®ããã«å€æŽããããšã«åãçµã¿ãŸããïŒ
ãããŠsettings.pyã§ïŒ