如何在axios中为不同主机使用Django的CSRF保护? [英] How to use Django's CSRF protection in axios for different host?

查看:56
本文介绍了如何在axios中为不同主机使用Django的CSRF保护?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将ReactJS项目作为前端,而将Django作为后端,并且在CSRF保护方面遇到了麻烦!

I am working on ReactJS project as frontend and Django as backend and having trouble with CSRF protection!

我正在使用Django CORS标头,并且已正确完成所有设置.只要我具有本地主机即可访问前端和后端,它就可以工作.我的前端在localhost:3006上运行,后端在localhost:8899端口上运行.因此,前端将设置 csrftoken cookie并随请求发送.

I am using Django CORS headers and I have done all set up correctly. It works as long as I have localhost to access both front and back ends. My frontend is running on localhost:3006 and backend us running on localhost:8899 port. So frontend is setting csrftoken cookie and sending it with post request.

我正在将 axios.create() withCredentials = true 一起使用,并且工作正常.现在,当我的同事从他的系统运行相同的前端代码,尝试连接到在我的计算机上运行的后端时,他得到了403 csrf cookie!目前,他在自己的本地主机 localhost:3006 上运行其前端,并连接到 my-ip:8899 的后端.所以我相信,当我们将 www.example.com 服务于前端并将 api.example.com 服务于后端作为前端主机的cookie时,我们在生产中也会遇到这个问题.不会发送到api主机!

I am using axios.create() with withCredentials = true and it works fine. Now when my co-worker is running same frontend code from his system, trying to connect to backend that is running on my machine, he is getting 403 csrf cookie not found! At this time, he is running his frontend on localhost:3006, his own localhost and connecting to backend of my-ip:8899. So I believe that we would have this problem too on production when we will have www.example.com serving frontend and api.example.com serving backend as cookies of frontend host wont get sent to api host!

我在Django中的cors标头设置,

My cors header settings in django,

# Origin white list
CORS_ORIGIN_WHITELIST = [
    'http://localhost',
    'http://127.0.0.1',
    'http://192.168.1.165',
    'http://192.168.1.165:3006',
]

CORS_EXPOSE_HEADERS = (
    'Access-Control-Allow-Origin: *',
)

# Allowed methods
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

# Allowed headers
CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'X-tz',
    'x-tz',
    'x-requested-with',
)

# # CSRF COOKIE NAME
CSRF_COOKIE_NAME = "csrftoken"

# To allow default credentials
CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_ALLOW_ALL = True

我的Axios创建代码是

and my Axios create code is,

let tz = "UTC";

try {
    tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
} catch (e) {
    consoleError(e);
}

const API = axios.create({
    baseURL: process.env.REACT_APP_API_HOST,
    timeout: 30000,
    withCredentials: true,
    xsrfCookieName: CSRF_COOKIE_NAME,
    xsrfHeaderName: "X-CSRFToken",
    headers: {'X-tz': tz}
});

因此,正如我所说,如果我使用本地主机/IP和端口将计算机连接到我的计算机,则可以正常工作,但是当我的同事尝试从其本地主机/IP前端连接到我的IP后端时,它却无法正常工作不允许他在没有CSRF Coo​​kie的情况下发出POST请求!我不想用装饰器绕过CSRF的Django安全性.那么有人可以告诉我我在做什么错吗?

So as I said, if I am connecting from my machine to my machine using localhost/IP and ports, it works but when my co-worker is trying to connect from his localhost/IP frontend to my ip-backend it doesn't allow him to make POST request without CSRF cookie! I don't want to bypass Django security of CSRF with decorator. So can anyone tell me what am I doing wrong here?

推荐答案

CSRF通过将cookie中的令牌与X-CSRFToken标头(或表单数据)中的令牌进行匹配来工作.您的axios请求必须同时发送两者.

CSRF works by matching the token in the cookie to the token in the X-CSRFToken header (or in the form data). Your axios request must sent both.

它正在X-CSRFToken中发送令牌.但是,它没有将Cookie发送到api.yourhost.com,因为该Cookie是为域www.yourhost.com设置的.这是Django中的默认设置.

It's sending the token in the X-CSRFToken. But it's not sending the cookie to api.yourhost.com because the cookie was set for the domain www.yourhost.com. That's the default in Django.

CSRF_COOKIE_DOMAIN 更改为以.开头的eTLD + 1域,即.yourhost.com,以便将其发送到您的每个子域,包括api.yourhost.com.

Change CSRF_COOKIE_DOMAIN to your eTLD+1 domain preceded by a ., i.e. .yourhost.com, so that it's sent to every of your subdomains, including api.yourhost.com.

现在在您的测试场景中,这将无法正常工作,因为由同事的前端设置的cookie是针对localhost的,而axios请求是针对您的ip的.除了让您的同事也从您的ip获取前端,没有其他解决方案.

Now in your test scenario, this cannot work, because the cookie set by your coworker's frontend is for localhost whereas the axios request is to your ip. There's no solution for this except have your co-worker get the frontend also from your ip.

这篇关于如何在axios中为不同主机使用Django的CSRF保护?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆