Webpack环境下Django无法设置sessionid Cookie问题求助
问题背景
用Webpack构建React前端应用,后端采用Django框架,计划基于session实现用户授权。发起登录请求后接口返回200 OK,响应头的Set-Cookie字段存在session-id,但浏览器Cookie列表中找不到该Cookie。改用create-react-app搭建相同功能时正常,尝试RTKQuery发起请求问题仍未解决。
现有代码
React 请求代码
await fetch("http://127.0.0.1:8000/api/v1/account/login", { method: "POST", body: JSON.stringify({ username: formData?.username, password: formData?.password, }), headers: { "Content-Type": "application/json", "X-CSRFToken": Cookies.get("csrftoken") as string, withCredentials: "include", // 错误位置 }, })
Webpack 配置
module.exports = { mode: isDev ? 'development' : 'production', devtool: isDev ? 'source-map' : false, target: 'web', entry: './src/index.tsx', output: { path: path.resolve(__dirname, 'build'), filename: '[name].[hash].bundle.js', clean: true }, devServer: { hot: isDev, compress: true, open: true, port: 4444, historyApiFallback: true, allowedHosts: ['all'], client: { overlay: { warnings: false }, logging: 'none', }, static: { directory: path.resolve(__dirname, 'src') } }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], alias: { '@components': path.resolve(__dirname, 'src/components'), '@assets': path.resolve(__dirname, 'src/assets'), '@my-types': path.resolve(__dirname, 'src/types'), '@hooks': path.resolve(__dirname, 'src/hooks'), '@slices': path.resolve(__dirname, 'src/slices'), '@': path.resolve(__dirname, 'src'), } }, optimization: { splitChunks: { chunks: 'all' }, minimizer: [ new CssMinimizerPlugin(), ] }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'public/index.html') }), new MiniCssExtractPlugin(), new ESLintPlugin({ context: path.resolve(__dirname, 'src'), extensions: ['.ts', '.tsx', '.js', '.jsx'], exclude: 'node_modules', }) ], module: { rules: [ { test: /\.(js|ts)x?$/, exclude: path.resolve(__dirname, 'node_modules'), use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react'] } } }, { test: /\.(css)$/i, exclude: path.resolve(__dirname, 'node_modules'), use: [MiniCssExtractPlugin.loader, 'css-loader'] }, { test: /\.(png|jpeg|jpg|ico|gif)$/, type: 'asset/resource' }, { test: /\.svg/i, use: ['url-loader'] } ] } }
解决方案
1. 修正 withCredentials 的位置
withCredentials 是 fetch 配置的顶级属性,不属于 headers 字段。调整位置并改为布尔值:
await fetch("http://127.0.0.1:8000/api/v1/account/login", { method: "POST", body: JSON.stringify({ username: formData?.username, password: formData?.password, }), headers: { "Content-Type": "application/json", "X-CSRFToken": Cookies.get("csrftoken") as string, }, withCredentials: true, // 移至顶级配置 })
若使用RTKQuery,需在基础查询配置中开启凭证携带:
const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: 'http://127.0.0.1:8000/api/v1/', credentials: 'include', // 开启凭证 }), // 其他配置 })
2. 配置 Webpack Dev Server 代理
跨域场景下浏览器会限制Cookie存储,添加代理转发请求避免跨域:
修改 devServer 配置:
devServer: { // 原有配置... proxy: { '/api': { target: 'http://127.0.0.1:8000', changeOrigin: true, secure: false, // 本地http开发环境设为false } } },
之后请求改为相对路径:
await fetch("/api/v1/account/login", { ... })
3. 确保 Django 端 CORS 配置正确
安装并配置 django-cors-headers,允许凭证和对应源:
- 安装依赖:
pip install django-cors-headers - 修改
settings.py:
INSTALLED_APPS = [ # 其他应用 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 放在最前面 'django.middleware.common.CommonMiddleware', # 其他中间件 ] # 允许本地前端源 CORS_ALLOWED_ORIGINS = [ "http://localhost:4444", "http://127.0.0.1:4444", ] # 允许携带凭证(关键) CORS_ALLOW_CREDENTIALS = True # Session Cookie 配置 SESSION_COOKIE_SAMESITE = 'Lax' # 生产https环境可设为'None' SESSION_COOKIE_SECURE = False # 本地http设为false,生产https设为true
内容的提问来源于stack exchange,提问作者tamirlan7
相关产品推荐
相关产品推荐

