cph2117
cph2117

Reputation: 2681

Django and React getting 403 forbidden

I've used create-react-app combined with Django Rest Framework to make a small site. Everything works perfectly when I use npm start and hit the Django API from one port to another. When I npm build the static react files and serve them from within the Django app, however, I get 403 forbidden when hitting a number of endpoints. I think it has something to do with CSRF, but I can't figure out what.

I serve the static files from views.py:

@api_view(['GET'])
def serve_html(request):
    try:
        with open(os.path.join(REACT_APP_DIR, 'build', 'index.html')) as f:
            return HttpResponse(f.read())
    except FileNotFoundError:
        return HttpResponse(
            """
            This URL is only used when you have built the production
            version of the app. Visit http://localhost:3000/ instead, or
            run `yarn run build` to test the production version.
            """,
            status=501,
        )

My urls.py contains the catchall for the static files at the bottom:

urlpatterns = [
    # ..all api paths
    url(r'^', serve_html, name='serve_html'),
]

I use TokenAuthentication and SessionAuthentication:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

And the api requests that require users to be logged in have the following decorators:

@authentication_classes((SessionAuthentication, TokenAuthentication))
@permission_classes((IsAuthenticated,))

Addendum: I notice that when running it cross-origin, there is no sessionid cookie (and things work), but when I try to host react files on same-origin, there is a sessionid cookie (and 403 Forbidden is returned).

Sorry for the open-endedquestion, but I'm at my wit's end here; I really don't know why it's not working.

Upvotes: 2

Views: 4164

Answers (1)

Haren Lewis
Haren Lewis

Reputation: 161

You do not require the SessionAuthentication class since you are using a token-based HTTP Authentication scheme. This should do the trick:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    )
}

Hope this helps.

Upvotes: 6

Related Questions