Cors Issue with React Frontend and Django Backend

Viewed 473

So I have build backend API in Django with inbuilt user module for authentication login etc.

The login API return Set Cookie in Response header when correct user and pass is passed.(Tested in Postman and works fine)

However when fetch function is called in reactJS, it's not setting Cookie in browser to be used later on further requests.

Django CORS Setting.

  ALLOWED_HOSTS = ["django-env-south-1.elasticbeanstalk.com", "*","127.0.0.1"]
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_WHITELIST = [
    'https://127.0.0.1:3000',
    'http://127.0.0.1:3000',
    'https://localhost:3000',
    'http://localhost:3000',
]
CSRF_TRUSTED_ORIGINS = [
    "127.0.0.1:3000",
    "localhost:3000",
]

Django API which return and Set-Cookie in response header

def signin(request):
    try:
        if request.method == 'POST':
            username = request.POST['username']
            password = request.POST['password']
            
            user = authenticate(request,username=username, password=password)
            print(str(user))
            
            
            if user is not None:
                login(request, user)
                fname = user.first_name
                # messages.success(request, "Logged In Sucessfully!!")
                sessionid=request.session.session_key
                return JsonResponse({"Status":"Success","session":sessionid})
            else:
                messages.error(request, "Bad Credentials!!")
                return JsonResponse({"Status":"Bad Credentials!!"},status=401)
        
        return render(request, "authentication/signin.html")
    except Exception as e:
        print(e)
    return("Crashed")

React Fetch Code

   var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
    
    var urlencoded = new URLSearchParams();
    urlencoded.append("username", `${users.username}`);
    urlencoded.append("password", `${users.password}`);

    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: urlencoded,
      redirect: 'follow',
      credentials: "include"

 };
 

//Fetching Login api
fetch("http://127.0.0.1:8000/authentication/signin", requestOptions)
  .then(response => response.text())
  .then(data => handleResult(JSON.parse(data)))
  .catch(error => console.log('error', error));
  }

Once Cookie is set in browser using below Code to pass Cookie in a new API Call. (But this is failing currently since Cookie is not set in request header as well)

let myHeaders = new Headers();
      let requestOptions = {
        method: 'GET',
        headers: myHeaders,
        credentials: "include"
      }; 
  
//Calling ME api
  fetch("http://127.0.0.1:8000/authentication/me", requestOptions)
    .then(response => response.text())
    .then(result => handleData(JSON.parse(result)))
    .catch(error => console.log('error', error));
1 Answers

You haven't set the CORS_ALLOW_CREDENTIALS setting. As mentioned in django-cors-headers' GitHub repo:

If True, cookies will be allowed to be included in cross-site HTTP requests. Defaults to False.

Specifying this would would set the Access-Control-Allow-Credentials header allowing the browser to expose the cookies to JavaScript.

Hence you need to add the following to your settings:

SESSION_COOKIE_SAMESITE = "None"
CORS_ALLOW_CREDENTIALS = True
Related