score:-1

i've got this problem once, i was using token authentication. that's how i solved it. but not sure if it is the best idea. i only used csrf_exempt for this view and all others views are viewsets.

@csrf_exempt
def get_current_user(request, *args, **kwargs):
    if request.method == 'get':
        user = request.user
        serializer = userdataserializer(user)
        return jsonresponse(serializer.data, safe=false)

my middleware in settings.py

middleware = [
   'django.middleware.security.securitymiddleware',
   'django.contrib.sessions.middleware.sessionmiddleware',
   'corsheaders.middleware.corsmiddleware',
   # 'django.contrib.auth.middleware.sessionauthenticationmiddleware',
   'django.middleware.common.commonmiddleware',
   'django.middleware.csrf.csrfviewmiddleware',
   'django.contrib.auth.middleware.authenticationmiddleware',
   'django.middleware.locale.localemiddleware',
   'oauth2_provider.middleware.oauth2tokenmiddleware',
   'django.contrib.messages.middleware.messagemiddleware',
   'django.middleware.clickjacking.xframeoptionsmiddleware',
   'auditlog.middleware.auditlogmiddleware',
]

score:0

to make csrf protection work you will need csrf cookie sent from django to react as a response to some request (like login or sth else). it will set cookie using set-cookie on frontend side. so make sure that you have a view that does that on django side. if not, create a view that as response generates that token.

how django (4.04) csrf validation work (simplified, based on middleware/csrf.py):

  1. gets csrf token from cookie (so frontend needs to resend it back on another request) - it might also get it from session but in case of react i would not use it

    def _get_token(self, request):
        ....
        try:
            cookie_token = request.cookies[settings.csrf_cookie_name]
        except keyerror:
            return none
    
  2. compares that cookie csrf token with non-cookie token from request:

    def _check_token(self, request):
        # access csrf_token via self._get_token() as rotate_token() may have
        # been called by an authentication middleware during the
        # process_request() phase.
        try:
            csrf_token = self._get_token(request)
        except invalidtokenformat as exc:
            raise rejectrequest(f"csrf cookie {exc.reason}.")
    
        if csrf_token is none:
            # no csrf cookie. for post requests, we insist on a csrf cookie,
            # and in this way we can avoid all csrf attacks, including login
            # csrf.
            raise rejectrequest(reason_no_csrf_cookie)
    
        # check non-cookie token for match.
        request_csrf_token = ""
        if request.method == "post":
            try:
                request_csrf_token = request.post.get("csrfmiddlewaretoken", "")
            except unreadableposterror:
                # handle a broken connection before we've completed reading the
                # post data. process_view shouldn't raise any exceptions, so
                # we'll ignore and serve the user a 403 (assuming they're still
                # listening, which they probably aren't because of the error).
                pass
    
        if request_csrf_token == "":
            # fall back to x-csrftoken, to make things easier for ajax, and
            # possible for put/delete.
            try:
                request_csrf_token = request.meta[settings.csrf_header_name]
            except keyerror:
                raise rejectrequest(reason_csrf_token_missing)
            token_source = settings.csrf_header_name
        else:
            token_source = "post"
    
        try:
            request_csrf_token = _sanitize_token(request_csrf_token)
        except invalidtokenformat as exc:
            reason = self._bad_token_message(exc.reason, token_source)
            raise rejectrequest(reason)
    
        if not _does_token_match(request_csrf_token, csrf_token):
            reason = self._bad_token_message("incorrect", token_source)
            raise rejectrequest(reason)
    

as you can see you either need to include csrfmiddlewaretoken in post request or include it in header with key: settings.csrf_header_name and value read from cookies on front-end side.

so for example you set withcredentials: true (to include initial cookie), read that initial csrf cookie in react and add to header in axios request at specific key.

when in question, i would just debug request setting up breakpoints in this code of django in middleware/csrf.py and you can trace what is missing and why csrf validation fails.


Related Query

More Query from same tag