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

Django+Graphene对接Nuxt前端POST请求403 Forbidden问题求助

解决Nuxt向Django-Graphene发送POST请求时的403 Forbidden错误

你遇到的问题核心是CSRF令牌传递异常,再加上请求格式和配置的小疏漏,导致前端请求被Django的CSRF防护拦截了。我帮你梳理几个关键修复点:

1. 修正Django的CORS配置错误

你的settings.py里CORS_ORIGIN_WHITELIST设置成了字符串,但Django要求它是数组类型,这会直接导致CORS验证不通过,进而影响CSRF令牌的正常传递:

# settings.py
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3000',
    'http://127.0.0.1:3000'  # 同时添加这两个地址,避免不同访问路径的兼容性问题
]
CORS_ALLOW_CREDENTIALS = True
CSRF_USE_SESIONS = False
CSRF_COOKIE_HTTPONLY = False
CSRF_COOKIE_SAMESITE = 'Lax'  # 建议改成Lax,None在部分浏览器可能存在兼容性问题

2. 修复Axios拦截器的代码问题

你在plugins/axios.js里的代码有两处明显问题:await用在onRequest上完全没必要(onRequest本身不需要异步),而且配置顺序和赋值逻辑可能导致Content-Type和X-CSRFToken变成undefined。修改成这样:

// plugins/axios.js
export default function ({ $axios, app }) {
  $axios.onRequest((config) => {
    // 先固定设置Content-Type,避免被后续操作覆盖
    config.headers.common['Content-Type'] = 'application/json'
    
    // 正确获取并设置CSRF令牌
    const csrfCookie = app.$cookies.get('csrftoken')
    if (csrfCookie) {
      config.headers.common['X-CSRFToken'] = csrfCookie
    }
    
    // 配置CSRF相关的Cookie和Header名称
    config.xsrfCookieName = 'csrftoken'
    config.xsrfHeaderName = 'X-CSRFToken'
    
    console.log('Request config:', config)
  })
}

另外要确保你已经安装并注册了@nuxtjs/axios和cookie-universal-nuxt插件,否则app.$cookies会无法正常使用。

3. 修正GraphQL请求的数据格式

你的store/contact.js里把AddMessage直接作为data发送,但GraphQL期望的是包含query、variables、operationName的JSON对象,而且你的variables是字符串格式,还多了一个多余的逗号,这都会导致请求解析失败:

首先修改queries/contact.js:

// queries/contact.js
export const AddMessage = {
  query: `
    mutation AddContact($input: AddMessageInput!){
      addMessage(input: $input){
        message{
          name email body terms
        }
      }
    }
  `,
  variables: {
    "input": {
      "name": "test",
      "email": "test@test.com",
      "body": "test",
      "terms": true
    }
  },
  operationName: 'AddMessage'
}

然后修改store/contact.js的请求逻辑:

// store/contact.js
import { AddMessage } from '../queries/contact.js'
export const actions = {
  async send() {
    try {
      // 先发送一个GET请求获取CSRF令牌(如果前端还未持有该Cookie)
      await this.$axios.get('/api/')
      
      const message = await this.$axios({
        url: 'api/',
        method: 'POST',
        data: AddMessage  // 现在是符合GraphQL要求的JSON格式
      })
      console.log('Request success:', message)
    } catch (error) {
      console.error('Request error:', error.response)
    }
  }
}

4. 确保CSRF令牌的正确传递

Django的CSRF防护要求请求必须携带从Cookie获取的令牌,所以在发送POST请求前,先发送一个GET请求到GraphQL端点,让后端主动设置csrftoken Cookie,这样前端才能拿到有效的令牌用于后续POST请求。

做完这些修改后,再测试请求,应该就能解决403错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:22:50