Angular调用Laravel接口取认证用户数据时报No query results for model错误
问题根因
- 最核心的问题是你的
/api/user路由没有添加认证中间件,未校验Token有效性:当Token过期/失效时,Laravel不会主动拦截请求,此时Auth::id()返回空值,执行User::where('id', null)->firstOrfail()时自然查询不到对应用户,抛出模型不存在的404错误。 - 前端没有处理Token过期的兜底逻辑,Token失效后仍持续携带本地存储的旧无效Token发起请求。
- 控制器代码冗余且错误处理不合理:加了认证中间件的前提下不需要再手动查询用户,且未登录场景应该返回401未认证错误,而非模型不存在的404。
- 小概率场景:Token对应的用户账号已被从数据库中物理删除,也会触发该报错。
修复步骤
- 给API路由添加认证中间件,根据你使用的认证驱动调整:
// 如果用Laravel Sanctum做Token认证 Route::get('/user', [UserController::class, 'user'])->middleware('auth:sanctum'); // 如果用Laravel Passport做Token认证 Route::get('/user', [UserController::class, 'user'])->middleware('auth:api');
添加中间件后,无效Token的请求会被直接拦截返回401未认证错误,不会进入控制器逻辑。
- 简化控制器代码,避免重复查询用户:
public function user() { // 经过auth中间件的请求,Auth::user()必然存在,无需二次查询 return response()->json(Auth::user()); }
- 前端添加全局请求错误拦截逻辑,捕获401状态码时清空本地存储的Token,跳转至登录页引导用户重新登录,以Angular的HttpInterceptor为例:
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { return next.handle(request).pipe( catchError((error: HttpErrorResponse) => { if (error.status === 401) { localStorage.removeItem('token'); // 跳转登录页逻辑 this.router.navigate(['/login']); } return throwError(() => error); }) ); }
- 按需调整Token有效期配置:
- 使用Sanctum的话修改
config/sanctum.php中的expiration参数,单位为分钟 - 使用Passport的话在
AuthServiceProvider的boot方法中设置Passport::tokensExpireIn()等过期规则
内容的提问来源于stack exchange,提问作者vega9231w
相关产品推荐
相关产品推荐

