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

Laravel Sanctum如何实现单API接口根据Token返回差异化内容?

同一路由兼容授权与未授权请求的解决方案

不需要创建两个路由,直接通过以下两种方式实现:

方法一:控制器内直接判断认证状态

先去掉路由上的强制认证中间件,让所有请求都能进入控制器,再根据用户是否认证返回不同数据:

路由定义

Route::post('/example', ExampleController::class);

控制器逻辑

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ExampleController extends Controller
{
    public function __invoke(Request $request)
    {
        // 检查当前请求是否有通过Sanctum认证的用户
        if ($request->user()) {
            // 给授权用户返回受保护数据
            return response()->json([
                'status' => 'success',
                'data' => [
                    'user_id' => $request->user()->id,
                    'protected_content' => '仅授权用户可见的专属内容'
                ]
            ]);
        }

        // 给未授权用户返回公开数据
        return response()->json([
            'status' => 'success',
            'data' => [
                'public_content' => '所有用户均可查看的公开内容'
            ]
        ]);
    }
}

方法二:自定义可选认证中间件(多路由复用场景)

如果多个路由都需要这种“可选认证”逻辑,可以自定义一个中间件,尝试认证但不强制返回401:

1. 创建中间件

执行Artisan命令生成中间件:

php artisan make:middleware OptionalSanctumAuth

2. 编写中间件逻辑

修改生成的app/Http/Middleware/OptionalSanctumAuth.php文件:

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;

class OptionalSanctumAuth extends Middleware
{
    protected function authenticate($request, array $guards)
    {
        // 尝试用Sanctum guard认证用户,成功则切换到该guard
        foreach ($guards as $guard) {
            if ($this->auth->guard($guard)->check()) {
                $this->auth->shouldUse($guard);
                return;
            }
        }
        // 认证失败不抛出401异常,继续执行后续请求
    }
}

3. 注册中间件别名

在app/Http/Kernel.php的$routeMiddleware数组中添加别名:

protected $routeMiddleware = [
    // 其他中间件...
    'auth.sanctum.optional' => \App\Http\Middleware\OptionalSanctumAuth::class,
];

4. 路由使用自定义中间件

Route::middleware('auth.sanctum.optional')->post('/example', ExampleController::class);

此时控制器里的逻辑和方法一完全一致,通过$request->user()判断用户状态即可。


内容的提问来源于stack exchange,提问作者Александр Инженер

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:33:19