我已经搜索了有关堆栈流和在线的所有问题,但根本没有任何效果。基本上我有使用 docker 支持的节点的 nginx,但我的前端在 docker 之外单独运行。现在,我在本地主机上运行 react 前端,在数字海洋上运行后端,但是当我想通过 nginx 访问后端中的路由时,我总是收到无效的 CSRF 令牌。我尝试在 cookie 和 header 中设置令牌,但仍然出现相同的错误
这是我的 nginx
worker_processes 1;
events {
worker_connections 1024;
}
http {
client_max_body_size 20M;
access_log off;
gzip on;
gzip_comp_level 3;
server {
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000' always;
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
location /socket.io/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000' always;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass http://backend:5000;
}
location /api {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:3000' always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers 'Authorization,X-CSRF-TOKEN,x-csrf-token,X-CSRF-Token,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range' always;
add_header Content-Type 'text/plain charset=UTF-8';
return 204;
}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass_header Set-Cookie;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass http://backend:5000;
add_header Access-Control-Max-Age 3600;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
这是反应
export const setCsrfToken = async (data) => {
return new Promise(async (res, rej) =>{
try {
const result = await axios.get(`${SERVER}/api/public/csrf-token`)
console.log(result.data)
axios.defaults.headers.common['X-CSRF-Token'] = result.data.csrfToken;
return res()
} catch (error) {
console.log(error.message)
return rej()
}
})
}
后端设置csrf
route.get('/csrf-token', async function (req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken())
return res.json({ csrfToken: req.csrfToken() });
})
后端检查csrf
app.use(cors({
credentials: true,
origin: 'http://localhost:3000'
}));
const csrfProtection = csrf({
cookie: true
})
app.disable('x-powered-by')
app.use(cloudinaryConfig.cloudinaryConfig);
app.use(cookieParser())
app.use(csrfProtection)
app.use(express.json())
app.use(express.urlencoded({
extended: false
}))