React前端对接Django后端出现403 Forbidden错误求助
Django + React 跨域登录403错误求助
后端返回错误信息:
Forbidden (Origin checking failed - http://localhost:3000 does not match any trusted origins.): /user/login/ [04/Mar/2024 18:17:23] "POST /user/login/ HTTP/1.1" 403 2568
React项目Axios配置
import axios from 'axios'; export const setCSRFToken = async () => { try { const response = await instance.get('/user/getCSRFToken/'); const csrfToken = response.data.CSRFToken; instance.defaults.headers.common['X-CSRFToken'] = csrfToken; console.log(csrfToken) console.log('Headers actualizados:', instance.defaults.headers); axios.defaults.withCredentials = true; } catch (error) { console.error('Error al obtener el token CSRF:', error); } }; export const instance = axios.create({ baseURL: 'http://127.0.0.1:8000', timeout: 5000, // tiempo de espera de 5 segundos headers: { 'Content-Type': 'application/json', }, }); // Llama a la función setCSRFToken para configurar el token CSRF al crear la instancia de Axios setCSRFToken();
Django项目settings.py配置
from pathlib import Path ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'products.apps.ProductsConfig', 'user.apps.UserConfig', 'partners.apps.PartnersConfig', 'corsheaders', 'django_cleanup.apps.CleanupConfig', ] 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 = 'Registro.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 = 'Registro.wsgi.application' # Database # https://docs.djangoproject.com/en/5.0/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'registro', 'USER': 'root', 'PASSWORD': 'Password*', 'HOST': 'localhost', 'PORT': '3306', } } AUTH_USER_MODEL = 'user.User' # Password validation # https://docs.djangoproject.com/en/5.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', }, ] # Configuracion de CORS CORS_ALLOWED_ORIGINS = ( 'http://localhost:3000', ) # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.contrib.auth.models.BigAutoField'
React登录组件代码
import React, { useState } from 'react'; import { Link, redirect } from 'react-router-dom'; import { Footer } from '../components/footer.js'; import { ButtonHideShow } from '../components/button-hide-show.js'; import '../stylesheets/login-register.css'; import { FaGoogle } from "react-icons/fa"; import { FaFacebook } from "react-icons/fa"; import { instance } from '../components/axios-config.js'; import axios from 'axios'; export const Login = () => { const [user, setUser] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [showPassword, setShowPassword] = useState(false); const [loggedIn, setLoggedIn] = useState(false); //Configuracion para importar los datos de inicio de sesión const handleLogin = async (e) => { e.preventDefault(); try { const response = await instance.post('/user/login/', { user, password }); console.log(response.data); setLoggedIn(true) } catch (error) { console.error('Error al iniciar sesión', error); setError('Usuario o contraseña incorrectos'); } }; if(loggedIn) { return redirect('/'); }; //Función para alternar la visibilidad de la contraseña const togglePasswordVisibility = () => { setShowPassword(!showPassword); }; return ( <div className='login-form'> <form className='container-login'> <h2>Inicio de Sesión</h2> <h3>Ingresa tus datos de inicio de sesión</h3> <input type='text' placeholder='Escribe tu usuario' className='user-dates' value={user} onChange={(e) => setUser(e.target.value)} required /> <div className='input-password'> <input type={showPassword ? 'text' : 'password'} placeholder='Escribe tu contraseña' className='user-dates' id='input-password' value={password} onChange={(e) => setPassword(e.target.value)} required /> <ButtonHideShow handleClick={togglePasswordVisibility} showPassword={showPassword}/> </div> <div className='container-access'> <div className='remember-me'> <input type='checkbox' className='check-login'></input> <p className='login-paragraph'>Recuérdame</p> </div> <Link to='/' style={{textDecoration:'none'}} className='login-paragraph'>¿Olvidaste tu contraseña?</Link> </div> <p style={{ color: 'red' }}>{error}</p> <button type='button' onClick={handleLogin} className='btn-sign-in'>Iniciar Sesión</button> <p className='login-paragraph-2'>O inicia sesión con:</p> <div className='container-btn-login-with'> <button className='btn-login-with'><FaGoogle />Google</button> <button className='btn-login-with'><FaFacebook />Facebook</button> </div> <p className='create-account'>¿Aun no tienes una cuenta? <Link to='/register' style={{textDecoration:'none'}} className='register-now'>Regístrate ahora</Link></p> </form> <Footer /> </div> ); };
已尝试方案
- 用
csrf_exempt装饰视图获取CSRF Token并在请求中使用 - 在Django配置中设置
CORS_ALLOWED_ORIGINS允许http://localhost:3000的请求
问题仍未解决,求其他可行解决方案。
内容的提问来源于stack exchange,提问作者Leonel Brizio
相关产品推荐
相关产品推荐

