如果项目中前后端使用了两个不同端口(例如:前端:5173,后端:81),这种情况属于跨域,Session 依赖 Cookie,而浏览器默认不会在跨域请求中携带 Cookie,所以直接用 Session 会失效。
解决方案:
方案一:Vite 代理(本地调试)
原理是让前端请求走 Vite 的本地代理转发到后端,对浏览器来说请求的是同一个源(localhost:5173),就不存在跨域了,Session/Cookie 自然正常工作。
修改 vite.config.js:
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'http://localhost:81',
changeOrigin: true
}
}
}
})
然后修改你的 axios 请求基础地址 (例如:在 src/api/request.js 或 axios 实例中):
arduino
const request = axios.create({
baseURL: '/api' // 所有请求都走代理
})
这样前端请求 /api/login 时,Vite 会自动转发到 http://localhost:81/login,浏览器认为是同源请求,Cookie/Session 完全正常。
注意:如果你的后端接口路径本身没有
/api前缀,可以加个 rewrite 去掉:
javascriptrewrite: (path) => path.replace(/^/api/, '')
方案二:JWT Token(多端融合)
什么时候才需要 JWT?
只有以下情况才值得引入 JWT:
- 需要同时支持 Web + App + 小程序 多端登录
- 后端需要 多台服务器水平扩展,不想搞 Session 共享(Redis)
- 前后端 无法部署在同一域名下(比如第三方平台嵌入)
- 后端登录成功后生成一个 JWT Token 返回给前端
- 前端把 Token 存到
localStorage - 之后每次请求在请求头带上
Authorization: Bearer xxx - 后端中间件校验 Token 判断登录状态
后端以TP6为例:
TP6 安装 JWT 库:
bash
composer require firebase/php-jwt
后端登录接口改造:
php
use Firebase\JWT\JWT;
public function login(Request $request)
{
// ... 前面的校验逻辑不变 ...
// 登录成功,签发 Token
$payload = [
'iss' => 'your-app',
'iat' => time(),
'exp' => time() + 3600, // 1小时过期
'data' => [
'user_id' => $user->id,
'username' => $user->username
]
];
$token = JWT::encode($payload, '你的密钥', 'HS256');
return json([
'code' => 200,
'msg' => '登录成功',
'data' => ['token' => $token]
]);
}
前端拿到 Token 后存储:
javascript
if (res.code === 200) {
localStorage.setItem('token', res.data.token)
router.push('/')
}
三、方案三:Nginx反向代理(推荐)
跨域和身份认证是两个独立的问题,Nginx 通过反向代理可以从根本上消除跨域,而 JWT 只是身份认证方案之一,两者互不依赖。
Nginx 解决跨域的原理
跨域限制只存在于浏览器和服务器之间,服务器与服务器之间的通信不受同源策略限制。
Nginx 反向代理的做法是:让前端请求发到 Nginx(同源),再由 Nginx 转发给后端(服务器间通信,无跨域)。对浏览器来说,全程都是同源请求,跨域问题直接"消失"了。
浏览器 → Nginx(同源,无跨域)→ 后端服务器
Nginx 配置示例
假设前端和后端部署在同一个域名下,Nginx 同时负责静态文件和 API 转发:
bash
server {
listen 80;
server_name your-domain.com;
# 前端静态文件
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
# API 请求转发到后端
location /api/ {
proxy_pass http://localhost:81/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这样前端请求 /api/login 时,Nginx 自动转发到 localhost:81/login,浏览器认为是同源请求,不需要任何 CORS 配置,也不需要 JWT。
补充:Nginx 反向代理让前后端变成同域,Session/Cookie 天然可用,跨域和认证问题同时解决,完全不需要 JWT。
JWT 的价值在于前后端无法同域的场景(比如多端应用、微服务架构),如果你的项目通过 Nginx 统一了域名,Session 方案就是最简单够用的选择。