React调用Django接口出现403 Forbidden错误的排查求助
问题描述
我使用React(运行在localhost:3000)和Django(REST API运行在localhost:8000)开发宿舍管理系统。目前在localhost:8000/api/login页面登录后,可通过localhost:8000/api/user获取JSON格式的用户数据;但从前端localhost:3000发起登录请求时,服务器返回200状态码,数据库sqlite3的last_login字段也已更新,不过重定向到localhost:3000/student-view页面后,发起GET请求到http://127.0.0.1:8000/api/user时出现403 Forbidden错误。
相关代码
views.py 用户验证代码
class UserLogin(APIView): permission_classes = (permissions.AllowAny,) authentication_classes = (SessionAuthentication,) def post(self, request): data = request.data assert validate_username(data) assert validate_password(data) serializer = LoginSerializer(data=data) ## Validates user data if serializer.is_valid(raise_exception=True): user = serializer.check_user(data) login(request, user) return Response(serializer.data, status=status.HTTP_200_OK)
class UserView(APIView): permission_classes = (permissions.IsAuthenticated,) authentication_classes = (SessionAuthentication,) def get(self, request): serializer = StudentViewSerializer(request.user) return Response({"user": serializer.data}, status=status.HTTP_200_OK)
Login.js 登录请求代码
function submitLogin(e) { e.preventDefault(); client.post( "/api/login", { username: username, password: password }, {withCredentials: true} ).then(response => { if (response.status === 200) { navigate("/student-view", {replace: true}); } return response; }).catch(err => { console.log("Error", err) }) }
StudentView.js 用户数据请求代码
const client = axios.create({ baseURL: "http://127.0.0.1:8000" }); function StudentView() { const [posts, setPosts] = useState([]); useEffect(() => { client .get("/api/user") .then((result) => { console.log(result.data); setPosts(result.data); }) .catch((error) => console.log(error)); }, []); return ( <div> {posts.map((data) => { return ( <div key={data.id}> <h4>{data.title}</h4> <p>{data.body}</p> </div> ); })} </div> ); }
settings.py CORS配置
CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://127.0.0.1", "http://0.0.0.0", ]
修复方案
1. 给Axios全局配置添加凭证携带
登录请求中加了withCredentials: true,但StudentView里的Axios实例没配置,导致会话Cookie无法传递到后端。修改StudentView的Axios配置:
const client = axios.create({ baseURL: "http://127.0.0.1:8000", withCredentials: true // 新增此行,确保跨域请求携带Cookie });
2. 完善Django CORS配置
- 补充
127.0.0.1:3000到允许来源列表,因为React实际运行在带端口的地址上 - 开启允许跨域携带凭证的配置
修改后的settings.py:
CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://127.0.0.1:3000", ] CORS_ALLOW_CREDENTIALS = True
3. 统一请求域名格式
前端请求尽量使用一致的域名(要么全用localhost,要么全用127.0.0.1),避免因域名不一致导致Cookie无法共享。比如把StudentView的baseURL改为http://localhost:8000,和登录请求的域名保持统一。
4. 验证Django会话中间件
确保settings.py的MIDDLEWARE列表中包含以下必要中间件,否则SessionAuthentication无法正常工作:
MIDDLEWARE = [ # ... 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # ... ]
内容的提问来源于stack exchange,提问作者Sung Jin-Woo
相关产品推荐
相关产品推荐

