Laravel10+Sanctum:如何在同一API判断用户认证状态并返回对应数据
Laravel 10 + Sanctum 实现带认证/无认证的API返回逻辑
问题分析
你的核心需求是让接口兼容两种状态:携带有效Sanctum token时返回用户信息,无有效token时返回空的UserData数组。原代码存在两个关键问题:
- 单个用户实例误用了
UserResource::collection()(该方法用于处理用户集合,而非单个用户模型) - 需确保路由配置允许游客访问,同时支持Sanctum自动识别认证token
解决方案
1. 路由配置(routes/api.php)
确保接口不需要强制认证,让Sanctum自动识别请求中的token:
// 无需auth:sanctum中间件包裹,未登录用户可访问,带有效token时自动认证 Route::get('/index', [YourController::class, 'index']);
2. 修正后的index接口代码
public function index(Request $request): JsonResponse { // 初始化UserData为空数组 $this->body['UserData'] = []; // 检查请求是否携带有效认证token,$request->user()会自动识别Sanctum token if ($user = $request->user()) { // 用make处理单个用户模型,而非collection $this->body['UserData'] = UserResource::make($user); } $categories = Menu::query()->where('active', 1)->orderBy('rank', 'ASC')->get(); $this->body['navbarData'] = MenuResource::collection($categories); return response()->json(['data' => $this->body, 'error' => ''], 200); }
3. 登录接口优化(可选)
原登录代码存在冗余,简化后更清晰:
public function login(Request $request): JsonResponse { $validate = $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); if (Auth::attempt($validate)) { $user = Auth::user(); $user->update(['fcm_token' => $request->fcm_token]); $this->message = __('front.login_successfully'); $token = $user->createToken($user->name)->plainTextToken; return response()->json([ 'message' => $this->message, 'token' => $token, 'user' => UserResource::make($user), 'error' => '' ], 200); } else { $this->message = __('front.auth_failed'); return response()->json(['message' => $this->message, 'error' => ''], 200); } }
关键说明
- 使用
$request->user()替代Auth::check()+Auth::user(),更简洁且适配Sanctum的认证逻辑:带有效Bearer token时返回用户实例,否则返回null - 单个用户必须用
UserResource::make(),collection仅用于处理多个用户的集合场景,误用会导致数据结构异常 - 路由不强制认证,保证未登录用户也能正常获取
navbarData,同时支持认证用户获取额外的用户信息
内容的提问来源于stack exchange,提问作者AhmedSamy
相关产品推荐
相关产品推荐

