Django Rest Framework удалить csrf
Я знаю, что есть ответы относительно Django Rest Framework, но я не мог найти решение своей проблемы.
у меня есть приложение, которое имеет аутентификации и некоторые функциональные возможности.
Я добавил новое приложение к нему, которое использует Django Rest Framework. Я хочу использовать библиотеку только в этом приложении. Также я хочу сделать запрос POST, и я всегда получаю этот ответ:
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
у меня есть следующий код:
# urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns(
'api.views',
url(r'^object/$', views.Object.as_view()),
)
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
class Object(APIView):
@csrf_exempt
def post(self, request, format=None):
return Response({'received data': request.data})
Я хочу добавить API без влияет на текущее приложение.
Так что мои вопросы, как я могу отключить CSRF только для этого приложения ?
9 ответов:
почему эта ошибка происходит?
это происходит из-за значения по умолчанию
SessionAuthenticationсхема, используемая DRF. ДРФ этоSessionAuthenticationиспользует фреймворк сеанса Django для аутентификации, которая требует проверки CSRF.когда вы не определяете ни одного
authentication_classesв вашем представлении/наборе представлений DRF использует эти классы аутентификации по умолчанию.'DEFAULT_AUTHENTICATION_CLASSES'= ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ),С ФПИ должен поддерживать оба сеанса и вне сеанса проверки подлинности на основе той же представления, он применяет проверку CSRF только для аутентифицированных пользователей. Это означает, что только аутентифицированные запросы требуют токенов CSRF, а анонимные запросы могут быть отправлены без токенов CSRF.
если вы используете API стиля AJAX с SessionAuthentication, вам нужно будет включить допустимый токен CSRF для любых" небезопасных " вызовов метода HTTP, таких как
PUT, PATCH, POST or DELETEзапросы.что же тогда делать?
теперь, чтобы отключить проверку csrf, вы можете создать пользовательский класс аутентификации
CsrfExemptSessionAuthenticationкоторый простирается от значения по умолчаниюSessionAuthenticationкласса. В этом классе аутентификации мы переопределимenforce_csrf()проверьте, что происходило внутри фактическогоSessionAuthentication.from rest_framework.authentication import SessionAuthentication, BasicAuthentication class CsrfExemptSessionAuthentication(SessionAuthentication): def enforce_csrf(self, request): return # To not perform the csrf check previously happeningна ваш взгляд, то вы можете определить
authentication_classesбудет:authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)это должно обрабатывать ошибку csrf.
простое решение:
In views.py, используйте фигурные скобки CsrfExemptMixin и authentication_classes:
# views.py from rest_framework.views import APIView from rest_framework.response import Response from django.views.decorators.csrf import csrf_exempt from braces.views import CsrfExemptMixin class Object(CsrfExemptMixin, APIView): authentication_classes = [] def post(self, request, format=None): return Response({'received data': request.data})
Если вы не хотите использовать аутентификацию на основе сеанса, вы можете удалить
Session Authenticationиз REST_AUTHENTICATION_CLASSES, и это автоматически удалит все проблемы на основе csrf. Но в этом случае просматриваемые API могут не работать.кроме того, эта ошибка не должна приходить даже с проверкой подлинности сеанса. Вы должны использовать пользовательскую аутентификацию, например TokenAuthentication, для своих API и обязательно отправлять
Accept:application/jsonиContent-Type:application/json(при условии, что вы используете json) в ваших запросах вместе с маркер аутентификации.
для всех, кто не нашел полезного ответа. Да DRF автоматически удаляет защиту CSRF, если вы не используете
SessionAuthenticationкласс аутентификации, например, многие разработчики используют только JWT:'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ),но проблема
CSRF not setможет произойти по какой-то другой причине, например вы не правильно добавили путь к вам посмотреть:url(r'^api/signup/', CreateUserView), # <= error! DRF cant remove CSRF because it is not as_view that does it!вместо
url(r'^api/signup/', CreateUserView.as_view()),
изменить urls.py
Если вы управляете своими маршрутами в urls.py, вы можете обернуть нужные маршруты с помощью csrf_exempt (), чтобы исключить их из промежуточного программного обеспечения проверки CSRF.
from django.conf.urls import patterns, url from django.views.decorators.csrf import csrf_exempt import views urlpatterns = patterns('', url(r'^object/$', csrf_exempt(views.ObjectView.as_view())), ... )альтернативно, как декоратор Некоторые могут найти использование декоратора @csrf_exempt более подходящим для их нужд
например,
from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponse @csrf_exempt def my_view(request): return HttpResponse('Hello world')должен получить работу!
Я поражен той же проблемой. Я следил за этим ссылка и это сработало. Решение заключается в создании промежуточного программного обеспечения
добавить disable.py файл в одном из ваших приложений (в моем случае это "myapp")
class DisableCSRF(object): def process_request(self, request): setattr(request, '_dont_enforce_csrf_checks', True)и добавить middileware в MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = ( myapp.disable.DisableCSRF, )
если вы используете виртуальную среду для вашего приложения, вы можете использовать следующий подход без эффективной любых других приложений.
то, что вы наблюдали, происходит потому что
rest_framework/authentication.pyэтот кодauthenticateметодSessionAuthenticationкласс:self.enforce_csrf(request)вы можете изменить
Requestкласс, чтобы иметь свойство с именемcsrf_exemptи инициализировать его внутри соответствующего класса цельюTrueесли вы не хотите проверки CSRF. Для пример:затем измените приведенный выше код следующим образом:
if not request.csrf_exempt: self.enforce_csrf(request)есть некоторые связанные изменения, которые вы должны были бы сделать это в
Requestкласса. Полная реализация доступна здесь (с полным описанием): https://github.com/piaxis/django-rest-framework/commit/1bdb872bac5345202e2f58728d0e7fad70dfd7ed
мое решение показано удар. Просто укрась мой класс.
from django.views.decorators.csrf import csrf_exempt @method_decorator(csrf_exempt, name='dispatch') @method_decorator(basic_auth_required( target_test=lambda request: not request.user.is_authenticated ), name='dispatch') class GenPedigreeView(View): pass
между изменениями DNS это также может быть фактором. Ожидание, пока DNS полностью сброшен, разрешит это, если он работал до проблем/изменений DNS.
Comments