Django @csrf_exempt不能在类视图中工作(Django @csrf_exempt not working in class View)
我在Django 1.9中有一个使用SessionMiddleware的应用程序。我想在同一个项目中为这个应用程序创建一个API,但是在做一个POST请求时,它不能使用@csrf_exempt注释。
settings.py
MIDDLEWARE_CLASSES = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'a9.utils.middleware.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'a9.core.access.middleware.AccessMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ] OAUTH2_PROVIDER = { # this is the list of available scopes 'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'} } CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', ) CORS_ALLOW_HEADERS = ( 'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ) REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', #'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': ( 'oauth2_provider.ext.rest_framework.OAuth2Authentication', #'rest_framework.authentication.TokenAuthentication', ) }
urls.py
urlpatterns = [ url(r'^v1/', include([ url(r'^', include(router.urls)), url(r'^auth/', MyAuthentication.as_view()), url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), url(r'^admin/', include(admin.site.urls)), ])), ]
views.py
@method_decorator(csrf_exempt, name='dispatch') class MyAuthentication(TemplateView): def post(self, request, *args, **kwargs): return HttpResponse('Hello, World!')
此后,我总是遇到一个CSRF验证失败的错误。
我找到了解决方法。您需要创建一个在任何Session Middlewares之前调用的中间件,然后检查您所需的URL或应用程序以免除CSRF令牌验证。所以代码将如下所示:
settings.py
MIDDLEWARE_CLASSES = [ 'api.middleware.DisableCSRF',#自定义中间件API 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common .CommonMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'a9.utils.middleware.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth .middleware.AuthenticationMiddleware', 'a9.core.access.middleware.AccessMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware .MessageMiddleware', 'django.middleware.clickjacking.XF rameOptionsMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ]
urls.py
app_name =“api” urlpatterns = [ url(r'^ v1 /',include([ url(r'^',include(router.urls)), url(r'^ auth /',MyAuthentication .as_view()), url(r'^ o /',include('oauth2_provider.urls',namespace ='oauth2_provider')), url(r'^ admin /',include admin.site.urls)), ])) ]
csrf_disable.py
from django.core.urlresolvers import resolve class DisableCSRF(object): """Middleware for disabling CSRF in an specified app name. """ def process_request(self, request): """Preprocess the request. """ app_name = "api" if resolve(request.path_info).app_name == app_name: setattr(request, '_dont_enforce_csrf_checks', True) else: pass # check CSRF token validation
这将只检查CSRF令牌具体的应用程序或URL,而不需要删除所有的CSRF。另外,这是django-rest-framework independent :)