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

Laravel 8未加auth:sanctum中间件时Auth facade失效解决方案

Laravel 8 单路由适配多角色API权限实现方案

问题核心原因

出现你描述的问题,本质是两个点:

  • 默认的auth:sanctum中间件属于强制认证中间件,只要请求没携带有效登录凭证,会直接返回401未授权,根本不会走到控制器逻辑,所以访客拿不到任何内容
  • 不挂载auth:sanctum中间件时,Sanctum的认证守卫不会被加载,Auth::check()永远返回false,自然识别不到已登录用户的身份

另外你的原有代码还有两个明显问题:

  • 存在语法笔误:Events:all()缺少一个冒号,正确写法是Events::all()
  • 性能问题:先调用->all()查询全表数据,再在内存中做where过滤,数据量稍大就会出现响应慢、内存占用高的问题

具体实现方案

不需要拆分多个路由,单路由即可适配访客、普通用户、管理员三类身份的返回逻辑,步骤如下:

1. 调整路由配置

路由不需要挂载强制认证的auth:sanctum中间件,正常写在公共路由组即可:

// routes/api.php
Route::get('view', [ViewController::class, 'show']);

2. 重写控制器show方法

在方法开头手动指定使用Sanctum守卫识别身份,这个操作不会拦截未登录请求,同时能正确解析请求携带的有效token,再根据用户身份拼接查询条件,直接在数据库层完成过滤:

<?php

namespace App\Http\Controllers;

use App\Models\Events;
use Illuminate\Support\Facades\Auth;

class ViewController extends Controller
{
    public function show()
    {
        // 指定当前请求使用sanctum守卫识别身份,不强制要求登录
        Auth::shouldUse('sanctum');
        
        // 初始化查询构造器
        $eventsQuery = Events::query();

        // 未登录用户、is_verified=0的普通用户,仅能查看已审核内容
        if (!Auth::check() || Auth::user()->is_verified !== 1) {
            $eventsQuery->where('is_verified', 1);
        }

        // 按需添加排序、分页逻辑,这里示例按创建时间倒序
        $eventsList = $eventsQuery->latest()->get();

        // 标准JSON响应返回,不要直接echo输出
        return response()->json($eventsList);
    }
}

测试说明

在Hoppscotch等接口测试工具中测试时:

  • 访客身份直接发起GET请求,不需要携带任何认证信息,会返回所有is_verified=1的已审核内容
  • 普通用户(is_verified=0)登录后,在请求头携带Authorization: Bearer {用户token},接口会识别身份,同样返回所有已审核内容
  • 管理员(is_verified=1)登录后携带对应token请求,会返回全部文章内容

优化建议

  • 不要在控制器中直接用echo输出数据,使用Laravel自带的response()->json()返回,会自动处理Content-Type头、数据格式转换,避免出现跨域、格式解析错误
  • 数据量较大时,建议把->get()替换为->paginate()分页查询,避免单次查询数据过多导致接口超时
  • 如果后续权限逻辑变复杂,可以把权限判断抽成中间件或者模型查询范围,减少控制器里的冗余逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:33:22