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

请求Laravel的api/user接口返回未认证的原因及解决方案

问题描述

本地环境中,Laravel 11.x Sanctum API部署在127.0.0.1:8000,ReactJS前端运行在localhost:5173,前后端跨域名。前两个请求(获取CSRF Cookie、登录)正常,但调用/api/user时返回未认证状态。

ReactJS代码片段:

await axios.get('/sanctum/csrf-cookie', { headers: {
    'accept': 'application/json',
    'Content-Type': 'application/json'
  }})
  const response = await axios.post('/api/login', payload, { headers: {
    'accept': 'application/json',
    'Content-Type': 'application/json'
  }});
  if (response) {
    const responses = await axios.get('/api/user', {
      headers: {
        'accept': 'application/json',
        'Content-Type': 'application/json'
      }
    });

    console.log(responses);
  }

当前配置:

  • .env文件:
SESSION_DOMAIN='.127.0.0.1:8000'
SANCTUM_STATEFUL_DOMAINS='localhost:5173'
  • cors.php文件:
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login'],
'allowed_origins' => ['http://localhost:5173'],
'supports_credentials' => true,
  • Login控制器方法:
public function login(Request $request)
{
    $validated = $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    if (Auth::attempt($validated)) {
        $token = auth()->user()->createToken('auth_token');

        return response()->json([
            'token' => $token,
        ]);
    }

    return response()->json(['error' => 'Invalid credentials'], 401);
}
原因分析
  1. 认证方式混淆:登录方法生成了Sanctum个人访问令牌,但前端调用/api/user时未使用该令牌认证,而是依赖Cookie会话。跨域名场景下,localhost和127.0.0.1被视为不同域名,Cookie无法跨域共享。
  2. SESSION_DOMAIN配置错误:Cookie的Domain属性不允许包含端口号,.127.0.0.1:8000格式无效,导致会话Cookie无法正确设置。
  3. 前端未配置跨域凭证携带:即使想依赖Cookie认证,axios需要开启withCredentials: true才能携带跨域Cookie,但本地不同域名的场景下这种方式本身不可行。
解决方案

方案一:个人访问令牌认证(推荐跨域名场景)

  1. 前端修改:登录成功后存储令牌,后续请求携带Authorization头:
await axios.get('/sanctum/csrf-cookie', { headers: {
    'accept': 'application/json',
    'Content-Type': 'application/json'
  }});
const response = await axios.post('/api/login', payload, { headers: {
    'accept': 'application/json',
    'Content-Type': 'application/json'
  }});

if (response.data.token) {
  localStorage.setItem('auth_token', response.data.token.plainTextToken);
  const userResponse = await axios.get('/api/user', {
    headers: {
      'accept': 'application/json',
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${localStorage.getItem('auth_token')}`
    }
  });
  console.log(userResponse);
}
  1. 后端路由配置:确保/api/user路由使用auth:sanctum中间件:
// routes/api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});
  1. env调整:移除无效的SESSION_DOMAIN配置:
SESSION_DOMAIN=''
SANCTUM_STATEFUL_DOMAINS='localhost:5173'

方案二:统一本地域名(Cookie会话认证,仅本地调试用)

  1. 修改hosts文件:添加两条域名映射:
127.0.0.1 app.test
127.0.0.1 api.app.test
  1. Laravel配置更新:
APP_URL=http://api.app.test
SESSION_DOMAIN='.app.test'
SANCTUM_STATEFUL_DOMAINS='app.test:5173'
  1. ReactJS启动配置:指定域名启动项目:
HOST=app.test PORT=5173 npm run dev
  1. axios全局配置:开启跨域凭证携带:
axios.defaults.withCredentials = true;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:22:09