You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React对接Django SessionAuthentication时CSRF Token缺失致请求被禁

Django + React SessionAuthentication 中CSRF Token无法读取的问题

更新说明:因内容过长,已简化表述

我正尝试在React(端口3000)与Django(端口8000)中实现SessionAuthentication,但遇到CSRF Token无法在React中设置的问题,导致/api/user请求返回FORBIDDEN。

复现步骤

注册、登录、刷新页面,运行以下命令:

Django(端口8000):

python3 -m venv backendvirtualenv && source backendvirtualenv/bin/activate
pip install -r requirements.txt
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

React(端口3000):

npm install
npm run build
npm start

相关代码配置

Django配置(settings.py):

CORS_ALLOWED_ORIGINS = [
    'http://localhost',
    'http://127.0.0.1',
    'http://0.0.0.0',
    'http://127.0.0.1:3000',
]

CORS_ORIGIN_ALLOW_ALL = True 

CORS_ALLOW_CREDENTIALS = True

INSTALLED_APPS = [
...
    'corsheaders',


MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',


REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
    ),
}

SESSION_COOKIE_HTTPONLY = True  # Default value is True, which is recommended
SESSION_COOKIE_SAMESITE = 'Lax' # Consider 'None' if strictly necessary and secure is set
SESSION_COOKIE_SECURE = False    # Non-Production Port 80

CSRF_COOKIE_HTTPONLY = False    # Should generally be False to allow JavaScript to read the value
CSRF_COOKIE_SECURE = False       # Non-Production Port 80

Django视图(views.py):

class UserLogin(APIView):
    permission_classes = (permissions.AllowAny,)
    authentication_classes = (SessionAuthentication,)
    ##
    def post(self, request):
...
        if serializer.is_valid(raise_exception=True):
            user = serializer.check_user(data) <-- authenticate is in here
            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 = UserSerializer(request.user)
        return Response({'user': serializer.data}, status=status.HTTP_200_OK)

React代码(App.js):

axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';
axios.defaults.withCredentials = true;

const client = axios.create({
  baseURL: "http://127.0.0.1:8000"
});

....


  function submitLogin(e) {
    e.preventDefault();

    client.post(
      "/api/login",
      {
        email: email,
        password: password
      }
    ).then(function(res) {

      setTimeout(() => {
          const csrftoken = Cookies.get('csrftoken');
          const sessionid = Cookies.get('sessionid');
          console.log("XXX /api/login csrftoken:" + csrftoken);    
          console.log("XXX /api/login sessionid:" + sessionid);  
          
          console.log('cookies', document.cookie)
          
        }, 100);       

        setCurrentUser(true);
    });    

问题分析

从日志可见,CSRF Token无法被读取:

App.js:103 XXX /api/login csrftoken:undefined
App.js:104 XXX /api/login sessionid:undefined
App.js:106 cookies  <--- 此处document.cookie为空

但/api/login的响应中确实存在CSRF Token:

Set-Cookie:
csrftoken=yO8XukEnOSWYgwYxae4nd7c2OEHF2UQG; expires=Mon, 10 Mar 2025 22:26:02 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Set-Cookie:
sessionid=rbj2ewpg11sx0t7q9j16ika01nk46074; expires=Mon, 25 Mar 2024 22:26:02 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax
Vary:

已尝试的方案

  • 将axios更新至最新版本1.6.7
  • 测试过Chrome和Edge浏览器
  • 代理配置方案无效
  • 使用fetch()时CSRF Token可被浏览器Cookie保存,但Axios和superagent均无效,希望解决Axios的适配问题

内容的提问来源于stack exchange,提问作者Axil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:35:11