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

Laravel Sanctum API认证用户为null导致500错误,交易及登出接口无法正常调用问题

Laravel Sanctum API认证用户为null导致500错误,交易及登出接口无法正常调用问题

别着急,我之前也碰到过类似的问题,大概率是配置或者模型的几个小细节没做好,咱们一步步来排查:

首先,一定要先看Laravel的日志文件,路径是storage/logs/laravel.log,500错误肯定会在这里留下具体的报错信息——比如是不是某个guard没配置、模型少了必要的trait,这比瞎猜高效太多了。

接下来按这几个方向检查:

1. 确认Karyawan模型是否引入了Sanctum必需的Trait

Sanctum依赖HasApiTokens trait来处理token的生成和验证,你的Karyawan模型必须加上它:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; // 必须引入这个

class Karyawan extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable; // 加到这里

    // 你的模型其他代码...
}

如果没加这个,哪怕登录能返回token,后续验证时也会直接报错导致500。

2. 配置auth.php里的Guard和Provider

因为你用的是自定义的Karyawan模型,而不是默认的User模型,所以必须在config/auth.php里配置对应的guard和provider:

首先在guards数组里,给sanctum指定正确的provider:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'sanctum' => [
        'driver' => 'sanctum',
        'provider' => 'karyawans', // 这里要指向你的karyawan provider
    ],
],

然后在providers数组里注册karyawan的provider:

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
    'karyawans' => [ // 新增这个
        'driver' => 'eloquent',
        'model' => App\Models\Karyawan::class,
    ],
],

如果这里配置错了,Sanctum会默认去查User模型,自然找不到你的Karyawan用户,导致Auth::user()返回null,甚至直接抛出500错误。

3. 登录接口要使用正确的Guard验证并生成Token

你的登录接口必须指定用karyawans guard来验证用户,而不是默认的web或user guard,否则生成的token和后续认证不匹配:

比如AuthController的login方法应该这样写:

public function login(Request $request)
{
    $credentials = $request->validate([
        // 这里换成你实际的登录字段,比如username/email
        'email' => 'required|email',
        'password' => 'required',
    ]);

    // 用karyawans guard验证 credentials
    if (!Auth::guard('karyawans')->attempt($credentials)) {
        return response()->json(['message' => '登录凭证无效'], 401);
    }

    // 获取当前登录的karyawan用户
    $user = Auth::guard('karyawans')->user();
    // 生成sanctum token
    $token = $user->createToken('auth_token')->plainTextToken;

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

4. 登出和交易接口里指定Guard获取用户

在TransaksiController和AuthController的logout方法里,最好明确指定用sanctum guard来获取用户,避免默认guard的问题:

比如TransaksiController的store方法:

public function store(Request $request)
{
    // 用sanctum guard获取用户
    $user = Auth::guard('sanctum')->user();

    if (!$user) {
        return response()->json([
            'message' => 'Unauthorized - Token tidak valid atau sudah expired',
            'debug' => [
                'auth_guard' => config('auth.defaults.guard'),
                'header_auth' => $request->header('Authorization'),
                'user_check' => Auth::guard('sanctum')->check()
            ]
        ], 401);
    }

    // 后续的验证和存储逻辑,比如:
    $validated = $request->validate([
        // 你的交易字段验证规则
        'amount' => 'required|numeric',
        // ...其他字段
    ]);

    // 自动加入id_karyawan
    $validated['id_karyawan'] = $user->id;

    $transaksi = Transaksi::create($validated);

    return response()->json($transaksi, 201);
}

登出接口的logout方法:

public function logout(Request $request)
{
    // 用sanctum guard获取用户并删除当前token
    Auth::guard('sanctum')->user()->currentAccessToken()->delete();

    // 如果要删除该用户所有token,可以改成:
    // Auth::guard('sanctum')->user()->tokens()->delete();

    return response()->json(['message' => '登出成功']);
}

最后检查Postman的请求头

确保你的请求头里Authorization字段是Bearer 你的token,注意Bearer后面有个空格,别漏了——有时候拼写错误或者空格缺失也会导致认证失败。

按照上面的步骤排查,应该就能解决Auth::user()为null和500错误的问题了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:49:31