【问题标题】:How to get CSRF from django in a separate React App如何在单独的 React App 中从 django 获取 CSRF
【发布时间】:2021-04-12 22:15:56
【问题描述】:

在研究了 CSRF 令牌和 django 之后,很明显 React 应用必须通过 django 渲染才能正常检索 CSRF 令牌(即注入 DOM)

我知道 instagram 的唯一原因是在他们的网络应用程序中使用 Django 和 React;我发现它极不可能被 django 渲染——至少以传统方式。

我意识到很难找到他们如何处理它的答案,但也许有人知道这样做的方法,而无需使用 django 渲染一个非常大的企业级 React 应用程序。

为了给出一些观点,我们的 react 应用程序位于与 django 驱动的 API 不同的子域上的单独 repo 和目录中。

我们已经在我能想到的每个领域寻求建议,但尚未找到合适的解决方案,因此我感谢您提供的任何反馈

【问题讨论】:

  • 浮现在脑海中的两个选项:1) 以您根本不需要 CSRF 保护的方式构建您的请求; 2) 使用专用的 CSRF 端点来获取令牌。
  • @KevinChristopherHenry你应该留下这个作为答案,因为其他受访者未能理解这个问题。我们采用了第一种方法,不确定这是一个长期的解决方案有多好
  • 如果试图帮助您的人误解了您的问题,请考虑离开 cmets 以消除混乱?
  • @Fush 大多数问题都假设我正在使用 django 来呈现 react 应用程序,但事实并非如此。所以抓取一个不存在的 cookie 是行不通的(另外两个答案)。首次呈现 react 应用程序时,cookie 不存在。我发现如何检索 cookie 的唯一方法是让登录 csrf 豁免(我不相信这不合适)
  • react 应用程序不必由设置 cookie 的同一应用程序呈现。您可以在任何/所有 API 调用上设置 cookie,并从那时起将其提供给 react 应用程序(假设您解决了潜在的 CORS 问题)。如果您特别希望能够在第一次渲染时做到这一点,那会改变一些事情,并且拥有一个专用的 csrf 端点可能是要走的路。

标签: django reactjs csrf


【解决方案1】:

我使用来自django.views.decorators.csrfget_token 来生成一个csrf 令牌。

views.py 中我的 django 代码:

from django.http import JsonResponse
from django.views.decorators.csrf import get_token

def get_csrf(request):
    return JsonResponse({"token":get_token(request)})

我在 react native 中调用了这个视图函数来获取一个 csrf 令牌: 我的反应式代码:

React.useEffect(()=>{ 
 fetch("api endpoint",{
 method:"GET",
 headers:{
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
 }).then((response)=>response.json())
.then((json)=>{
    //save your csrf-cookie (i use secure store to save it) 
   })
},[]);

【讨论】:

    【解决方案2】:

    你可以像这样生成一个 csrf 令牌:

    from django.middleware.csrf import get_token
    csrf_token = get_token(request)
    

    【讨论】:

    • 那么你如何将它传递给客户端(即 React 应用程序)?
    • 嗨,Jake,如果您的 react 应用程序位于不同的子域,那么您只需将 settings.py 中的 CSRF_COOKIE_DOMAIN 设置为您的 react 应用程序 url,即 react.example.com(假设您 django 应用程序的 url 是示例.com)。然后django会在CSRF_COOKIE_DOMAIN上设置csrf cookie。
    【解决方案3】:

    您可以将 csrf 令牌存储在 cookie 中,必要时使用 ensure_csrf_cookie,并将标头添加到 XHR 请求:

    import Cookies from 'js-cookie';
    
    Request.post(url)
        .set('X-CSRFToken', Cookies.get('csrftoken'))
        .send(data)
    

    【讨论】:

      猜你喜欢
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2022-11-05
      • 1970-01-01
      • 2021-08-29
      • 2017-06-25
      • 2021-10-07
      相关资源
      最近更新 更多