sei-ec-remote / project-4-issues

Open an issue to receive help on project 4
0 stars 0 forks source link

CORS issue - django and react #212

Closed caitreid closed 1 year ago

caitreid commented 1 year ago

What stack are you using?

(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)

DR

What's the problem you're trying to solve?

Trying to test the connection between my REST API and Frontend

Post any code you think might be relevant (one fenced block per file)

React api/mangos.js

import apiUrl from '../apiConfig'
import axios from 'axios'

export const getAllMangos = () => {
    return axios(`${apiUrl}/mangos`);

}

src/api/components/mangos/IndexMangos.js

import React, { useState, useEffect } from 'react';
import { getAllMangos } from '../../api/mangos'
import { Link } from 'react-router-dom'

const IndexMangos = (props) => {

    const [mangos, setMangos] = useState(null)

    useEffect(() => {
        getAllMangos()
            .then(res => setMangos(res.data.mangos))
            .catch(err => console.log(err))

        console.log('mangos ', mangos)
    }, []);

    if (!mangos) {
        return <p>Loading</p>

    } else if (mangos.length === 0) {

        return (
            <div className='container'>
                <p>No mangos yet, go add some</p>
            </div>
        )
    }

    const { user } = props

    const mangoCards = mangos.map((mango, id) => {
        <div key={id}>
            {mango.name}
            {mango.ripe}
        </div>
    })

    return (
        <div>
            <h1>Mangooooos</h1>
            {mangoCards}
        </div>

    )
}

export default IndexMangos
Screenshot 2023-03-08 at 5 44 05 PM

Django

"""
Django settings for django_auth_template project.

Generated by 'django-admin startproject' using Django 3.0.2.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""

import os
import sys
import dj_database_url
# import dotenv

# .env config:
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())

# Determine if we are on local or production
if os.getenv('ENV') == 'development':
  # If we are on development, use the `DB_NAME_DEV` value
  # from the .env file as the database name
  DB_NAME = os.getenv('DB_NAME_DEV')
  DB = {
      'ENGINE': 'django.db.backends.postgresql',
      'NAME': DB_NAME,
  }
  # Set debug to true
  DEBUG = True
  # Only allow locally running client at port 3000 for CORS
  CORS_ORIGIN_WHITELIST = ['http://localhost:3000']
  CORS_ORIGIN_ALLOW_ALL = True   
else:
  # If we are on production, use the dj_database_url package
  # to locate the database based on Heroku setup
  DB = dj_database_url.config()
  # Set debug to false
  DEBUG = False
  # Only allow the `CLIENT_ORIGIN` for CORS
  CORS_ORIGIN_WHITELIST = [
    os.getenv('CLIENT_ORIGIN')
  ]

# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
# Default database as defined above depending on development
# or production environment
DATABASES = {
    'default': DB
}

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
# This uses either a .env key or Heroku config var called SECRET
SECRET_KEY = os.getenv('SECRET')

# Application definition

INSTALLED_APPS = [
    # Our custom apps
    'api',
    # DRF
    'rest_framework',
    'rest_framework.authtoken',
    # Django built-in
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'more_please.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'more_please.wsgi.application'

# Django Rest Framework
#
# The default authentication class for all views will be TokenAuthentication
# which defines how we authenticate
# https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
#
# The default permission class for all views will be IsAuthenticated to require
# authentication for access
# https://www.django-rest-framework.org/api-guide/permissions/#isauthenticated
#
# These can be overridden on individual views
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 'rest_framework.authentication.TokenAuthentication'
        'rest_framework.authentication.SessionAuthentication'
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated'
    ]
}

# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Allow all host headers
ALLOWED_HOSTS = ['localhost']

# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
# optional package: http://whitenoise.evans.io/en/stable/django.html
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# Use the custom user model as the auth user for the admin view
AUTH_USER_MODEL = 'api.User'

If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?

Getting CORS error at localhost:3000/mangos

Screenshot 2023-03-08 at 5 43 55 PM

But interestingly when I look at the server requests I see an "OPTIONS" request at /mangos

Screenshot 2023-03-08 at 5 45 36 PM

What is your best guess as to the source of the problem?

Something's messed up with the CORS settings

What things have you already tried to solve the problem?

Making sure I have the right python packages installed, making updates to settings.py to allow access to localhost & localhost:3000

Paste a link to your repository here https://github.com/caitreid/more-please_backend https://github.com/caitreid/more-please_frontend

caitreid commented 1 year ago

I think this may help: https://stackoverflow.com/questions/50732815/how-to-use-csrf-token-in-django-restful-api-and-react

asands94 commented 1 year ago

Hey Cait, can you share your recent frontend code so we can take a look at how you have it setup!

caitreid commented 1 year ago

This turned out to be a Django-env issue. I was installing python packages inside the repo instead of at the top-level folder as we had done in class. Ashley pointed me in the right direction though!