alex
alex

Reputation: 21

django built-in authentication system not working with react

I am building a django-react app, using Django to render the templates, Django REST framework for the api endpoints, and React on top of django templates. I am using 'rest_framework.authentication.SessionAuthentication' and I have implemented the authentication routes but django's built-in authentication methods (login, logout, authenticate) only seem to work with the templates rendered by django and not with the React components. By this I mean if i have a view like

def home_page(request, *args, **kwargs):
    print("local USER >>>", request.user)
    print("local SESSION >>>", request.session)
    return render(request, 'pages/homepage.html',
        {}, status=200)

and I visit the route after logging in, it would print out both the user and the session object. But for the api views,

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticatedOrReadOnly])
def post_list_view(request, *args, **kwargs):
    print("api USER >>>", request.user)
    print("api SESSION >>>", request.session)
    ...

I get AnnonymousUser and None even if I'm logged in.

When i checked the browser cookies, i found both the csrftoken and sessionid cookies. But if I try a post request, I get 403 Forbidden error with "Authentication credentials were not provided." message. (I have also set withCredentials to true.) And in the request headers there was only the X-CSRFToken header (with the token) but sessionid cookie was missing.

At this point, I just don't know what to do next. Should I manually set the session cookie? Or, should I customize the built-in methods? (If so, please tell me how I could do that.) What am I doing wrong here and how can I fix it?

edit:

xhr headers for GET request: xhr headers for GET request

xhr headers for POST request: xhr headers for POST request

axios configurations:

const options = {
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-CSRFToken': csrftoken
    },
    withCredentials: true 
};

axios.post(url, data, options)
.then(response => {
    console.log(response);
    commentInput.current.value = '';
})
.catch(error => console.log(error));

Upvotes: 1

Views: 574

Answers (2)

alex
alex

Reputation: 21

turns out i was making a request to localhost and for some reason you cannot set cookies to it. the issue was solved by simply changing the url to 127.0.0.1.

Upvotes: 1

pplonski
pplonski

Reputation: 5859

Setting withCredentials should to the job:

axios.defaults.withCredentials = true

Do you set it this way?

If it doesn't help, could you please post server response header, the client request header and the axios config and example how you send request (on client).

One question, why did you go with Django templates + React? Why you didn't separate React from Django?

Upvotes: 0

Related Questions