Django CSRF 和 axios 发布 403 Forbidden

Posted

技术标签:

【中文标题】Django CSRF 和 axios 发布 403 Forbidden【英文标题】:Django CSRF and axios post 403 Forbidden 【发布时间】:2020-06-21 13:23:17 【问题描述】:

我将 Django 与石墨烯用于后端,将 Nuxt 用于前端。当我尝试从 nuxt 向 django 发布请求时出现问题。在邮递员中一切正常,在 nuxt 我收到 403 错误。

Django

# url.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', GraphQLView.as_view(graphiql=settings.DEBUG,
                                     schema=schema)),
]
# settings.py

CORS_ORIGIN_WHITELIST = 'http://localhost:3000'
CORS_ALLOW_CREDENTIALS = True
CSRF_USE_SESIONS = False
CSRF_COOKIE_HTTPONLY = False
CSRF_COOKIE_SAMESITE = None

NuxtJs

# nuxt.config.js

axios: 
  baseURL: 'http://127.0.0.1:8000/',
  debug: false,
  progress: true,
  credentials: true
,
# plugins/axios.js

await $axios.onRequest((config) => 
    config.headers.common['Content-Type'] = 'application/json'
    config.xsrfCookieName = 'csrftoken'
    config.xsrfHeaderName = 'X-CSRFToken'
    const csrfCookie = app.$cookies.get('csrftoken')
    config.headers.common['X-CSRFToken'] = csrfCookie
    console.log(config)
# store/contact.js

import  AddMessage  from '../queries/contact.js'

export const actions = 
  async send() 
    const message = await this.$axios(
      url: 'api/',
      method: 'POST',
      data: AddMessage
    )
  


# 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'

有点像

Here 是来自 axios 帖子的请求标头。对我来说奇怪的是值错误的 cookie。 X-CSRFToken 标头中存在 token 的良好价值。

Here 是来自 axios post 请求的日志。对我来说另一个奇怪的是未定义的标头:Content-Type 和 X-CSRFToken

谢谢!

【问题讨论】:

尝试从 settings.py 的中间件中删除 'django.middleware.csrf.CsrfViewMiddleware',。虽然这应该只在开发环境中完成。 我正在寻找生产解决方案。谢谢 nuxt 应用程序会在不同的域/子域上运行吗?如果是这样,那么您不能将 CSRF 用于该 API。 【参考方案1】:

我解决了这个问题,我想在这里分享解决方案。

错误 cookie 值的问题是由管理(我不记得如何)从后端应用程序获取 csrf cookie 的前端应用程序产生的。在 X-CSRFToken 标头中是从响应的 Set-cookie 标头中接收到的令牌,在 Cookie 标头中是来自后端应用程序的 cookie。

在我将 localhost 更改为 127.0.0.1 并添加之后 config.xsrfCookieName = 'csrftoken' 在 axios 插件中 我能够分离应用程序,独立保存和使用 cookie。

第二个问题,带有未定义的标头是由 axios 生成的。这两行代码解决了这个问题。这些也是在 axios onRequest 方法中添加的。

config.xsrfHeaderName = 'X-CSRFToken'
config.headers['Content-Type'] = 'application/json'

【讨论】:

以上是关于Django CSRF 和 axios 发布 403 Forbidden的主要内容,如果未能解决你的问题,请参考以下文章

带有 Axios 的 Django CSRF 令牌

axios通过django的csrf验证

如何使用 Axios 将 CSRF Coo​​kie 从 React 发送到 Django Rest Framework

Django AJAX方式提交数据解决csrf验证问题

Django AJAX方式提交数据解决csrf验证问题

Django(DRF)和React - 禁止(未设置CSRF cookie)