gpt4 book ai didi

django - 让 Django、VUE、CORS 和 CSRF 与真实世界的例子一起工作

转载 作者:搜寻专家 更新时间:2023-10-30 22:16:31 27 4
gpt4 key购买 nike

我真的被困住了。这就是我想要做的。

  1. 保持 CSRF 开启。 - 请不要让我把它关掉。
  2. 我有一个由 Django 和 Django Rest Framework 运行的 API 应用
  3. 我有一个由 Vue 运行的前端应用
  4. 我已经安装了 django-cors-headers 来管理 CORS

本地一切正常。一旦将其投入生产,我就开始收到 CSRF 错误。以下是一切的运作方式。

我看到了所有的答案,从关闭 CSRF 到允许所有的一切。我想正确地做这件事,而不是关闭所有东西然后打开所有东西,然后以安全漏洞告终。

所以,这就是我所拥有的。

已安装:django-cors-标题django-rest-框架drf-嵌套路由器...和其他

我的 api 在 api.websitename.com 上运行,Vue.js 应用程序在 websitename.com 上运行。

GET 请求非常有效。OPTION 请求似乎有效。

任何有风险的请求都不行。

对于我的 CORS,我在其他 MIDDLEWARE 之前安装了 'corsheaders.middleware.CorsMiddleware',

那么我的 CORS 设置是:

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'*.websitename.com',
)

我的 CSRF 设置是:

CSRF_TRUSTED_ORIGINS = [
"api.websitename.com",
]

无论我怎么玩这些,我最终都会遇到 CSRF token 错误。

我已经尝试在我的 Vue App.vue 文件中执行类似的操作:

mounted () {
this.getCSRFToken()
},
methods: {
getCSRFToken () {
return axios.get('token/').then(response => {
axios.defaults.headers.common['x-csrftoken'] = Cookies.get('csrftoken')
}).catch(error => {
return Promise.reject(error.response.data)
})
}
}

我的想法是,一旦应用程序加载到浏览器中,我就会获得一个 CSRF token 。但即便如此,当应用程序尝试执行除 GET 或 OPTION 之外的任何操作时,我仍会收到失败的 CSRF token 错误。

这是返回 token 的 View ,以防您好奇:

class CSRFTokenView(APIView):
permission_classes = (permissions.AllowAny,)

@method_decorator(ensure_csrf_cookie)
def get(self, request):
return HttpResponse()

我意识到我可能会在这里混淆问题,但欢迎任何可以帮助我解决问题的建议。

最佳答案

首先你要使用SessionAuthentication :

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

这将强制执行 CSRF,匿名用户除外(稍后会详细介绍)。对于浏览器前端,最简单的解决方案是让(浏览器)前端和后端都在同一个域下——这可以让你避免 CORS——正如上面评论所建议的那样。如果您有其他客户端,则只需使用 token (DRF token 或 JWT)——但由于存在 XSS 攻击的危险,这些对于浏览器的使用并不安全(将 token 存储在 localStorage 中本质上是不安全的)。

由于您使用的是 axios,因此 CSRF 设置非常简单:

import axios from 'axios'

axios.defaults.xsrfHeaderName = 'X-CSRFToken'
axios.defaults.xsrfCookieName = 'csrftoken'

因此,您应该在强制执行 CSRF 的情况下进行安全 session 。几乎。引用上面的链接页面:

Warning: Always use Django's standard login view when creating login pages. This will ensure your login views are properly protected.

CSRF validation in REST framework works slightly differently to standard Django due to the need to support both session and non-session based authentication to the same views. This means that only authenticated requests require CSRF tokens, and anonymous requests may be sent without CSRF tokens. This behaviour is not suitable for login views, which should always have CSRF validation applied.

这很棘手 - 您要么只使用 Django 服务器端 View ,这会使您的 SPA 设计稍微复杂一些,要么在 DRF 中重新创建登录和其他身份验证 View ,但要注意使用 @csrf_protect方法装饰器在这些“匿名” View 上强制执行 CSRF。显然,这样的 View 会破坏使用 token 的客户端,因此您可能希望为这些使用不同的端点(可能重新使用相同的基类)。因此,您的浏览器登录使用 /auth/browser/login/ 和您的移动登录 /auth/mobile/login/,前者使用 @csrf_protect 包裹>.

在研究了 contrib auth 源代码之后,应该仔细地从头开始重新创建登录和其他 auth View ;对于 Vanilla 要求,我会推荐预先存在的解决方案,如 django-rest-authdjango-all-auth .然而,django-rest-auth 包并不是为浏览器前端设计的,它强制使用 token 生成,而且您需要如上所述包装 View 。另一方面,all-auth 为 JS 客户端提供 AJAX 响应,可能是更好的选择。

关于django - 让 Django、VUE、CORS 和 CSRF 与真实世界的例子一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54836387/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com