You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3 + Express代理服务器用户认证问题(CORS相关)

问题描述

我正在使用某API进行Vue 3与Express的开发测试,通过Postman和curl可正常访问接口,但Vue应用无法正常运行。经排查,代理服务器已与应用通信,在运行于http://localhost:8080/login的Vue应用提交登录请求时,已成功获取token并添加至Authorization请求头,但获取用户详情接口始终无法正常工作,怀疑是CORS问题导致。恳请各位提供帮助,谢谢。

代理服务器代码(proxy-server/server.js)

//proxy-server/server.js

// Use Cors
app.use(cors({ origin: 'http://localhost:8080', credentials: true,  optionsSuccessStatus: 200 })); 
app.use(express.json());

app.get('/', (req, res) => {
  res.send('Hello, this is the proxy server!');
});

// Handle OPTIONS request for preflight checks
app.options('/authentication', cors());
app.options('/users/me', cors());
app.get('/v2.1/authentication', cors(), async (req, res) => {
  try {
    const response = await axios.get('https://blood.arc.cubeapis.com/v2.1/authentication', {
      headers: req.headers,
    });

    res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, Content-Type, Access-Control-Request-Headers, Authorization');
    res.header('Access-Control-Max-Age', '86400');

    res.json(response.data);
  } catch (error) {
    console.error('Proxy Error:', error.message);
    res.status(500).json({ error: 'Internal Server Error located  @ /v2.1/authentication' });
  }
});

app.post('/authentication', cors(), async (req, res) => {
  console.log('Received POST request:', req.method, req.url);
  console.log('Request headers:', req.headers);
  console.log('Request body:', req.body);

  try {
    const response = await axios.post('https://blood.arc.cubeapis.com/v2.1/authentication', req.body);

    res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, Content-Type, Access-Control-Request-Headers, Authorization');
    res.header('Access-Control-Max-Age', '86400');

    res.json(response.data);
  } catch (error) {
    console.error('Proxy Error:', error.message);
    res.status(500).json({ error: 'Internal Server Error /authentication' });
  }
});

app.get('/users/me', cors(), async (req, res) => {
  console.log('Received GET request:', req.method, req.url);
  console.log('Request headers:', req.headers);
  console.log('Request body:', req.body);
  console.log('Forwarding to:', 'https://blood.arc.cubeapis.com' + req.url);
  try {
    
    const response = await axios.get('https://blood.arc.cubeapis.com/v2.1/users/me', {
      headers: req.headers,
    });

    res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, Content-Type, Access-Control-Request-Headers, Authorization');
    res.header('Access-Control-Max-Age', '86400');

    res.json(response.data);


  } catch (error) {
    console.error('Proxy Error:', error.message);
    res.status(500).json({ error: 'Internal Server Error /v2.1/users/me', details: error.message });
    
  }
});
解决方案

1. 移除重复的CORS配置

你已经通过app.use(cors({...}))做了全局CORS配置,不需要再给每个路由单独加cors()中间件,重复配置会导致头信息冲突。全局配置会自动处理OPTIONS预检请求,也不用单独写app.options路由。

2. 清理冗余响应头

全局CORS中间件会自动生成规范的响应头,无需在每个路由里重复用res.header设置,避免头信息重复或不符合浏览器校验规则。

3. 过滤不必要的请求头

转发请求到目标API时,host、origin这类头可能会被目标服务器拒绝,建议过滤后再转发:

const { host, origin, ...forwardHeaders } = req.headers;
const response = await axios.get('https://blood.arc.cubeapis.com/v2.1/users/me', {
  headers: forwardHeaders,
});

4. 确认Vue请求配置

Vue发送请求时必须开启withCredentials,否则浏览器不会携带凭证,和你的CORS配置匹配:

// Vue中axios请求示例
axios.get('/users/me', {
  withCredentials: true,
  headers: {
    'Authorization': `Bearer ${token}`
  }
})

修正后的代理服务器代码

//proxy-server/server.js
const express = require('express');
const cors = require('cors');
const axios = require('axios');

const app = express();

// 全局CORS配置,覆盖所有路由
app.use(cors({ 
  origin: 'http://localhost:8080', 
  credentials: true,  
  optionsSuccessStatus: 200,
  allowedHeaders: ['Origin', 'Content-Type', 'Authorization'],
  methods: ['GET', 'POST', 'OPTIONS']
})); 
app.use(express.json());

app.get('/', (req, res) => {
  res.send('Hello, this is the proxy server!');
});

app.get('/v2.1/authentication', async (req, res) => {
  try {
    const { host, origin, ...forwardHeaders } = req.headers;
    const response = await axios.get('https://blood.arc.cubeapis.com/v2.1/authentication', {
      headers: forwardHeaders,
    });
    res.json(response.data);
  } catch (error) {
    console.error('Proxy Error:', error.message);
    res.status(500).json({ error: 'Internal Server Error located @ /v2.1/authentication' });
  }
});

app.post('/authentication', async (req, res) => {
  console.log('Received POST request:', req.method, req.url);
  console.log('Request headers:', req.headers);
  console.log('Request body:', req.body);

  try {
    const response = await axios.post('https://blood.arc.cubeapis.com/v2.1/authentication', req.body);
    res.json(response.data);
  } catch (error) {
    console.error('Proxy Error:', error.message);
    res.status(500).json({ error: 'Internal Server Error /authentication' });
  }
});

app.get('/users/me', async (req, res) => {
  console.log('Received GET request:', req.method, req.url);
  console.log('Request headers:', req.headers);
  console.log('Forwarding to:', 'https://blood.arc.cubeapis.com/v2.1/users/me');
  try {
    const { host, origin, ...forwardHeaders } = req.headers;
    const response = await axios.get('https://blood.arc.cubeapis.com/v2.1/users/me', {
      headers: forwardHeaders,
    });
    res.json(response.data);
  } catch (error) {
    console.error('Proxy Error:', error.message);
    res.status(500).json({ error: 'Internal Server Error /v2.1/users/me', details: error.message });
  }
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Proxy server running on http://localhost:${PORT}`);
});

内容的提问来源于stack exchange,提问作者dunkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:07:42