使用JWT时在Laravel Blade获取用户ID报非对象错误如何解决
错误原因
这个报错本质是auth()->guard('api')->user()返回了null,在非对象上读取id属性自然会抛错,常见触发原因有两个:
- 你渲染的是web路由下的页面,这类路由默认走基于session的
web认证守卫,你代码里却指定用api守卫取用户。JWT驱动的api守卫是无状态设计,只会从请求头的Authorization: Bearer <token>或者约定的请求参数里解析token识别用户,普通web页面请求不会携带JWT token,api守卫找不到登录态就直接返回null。 - 就算是在API场景下返回视图,你没有提前判断用户登录状态,遇到token过期、未携带token的请求时,
user()返回null就会触发报错。
修复方法
根据实际业务场景选对应方案即可:
- 普通服务端渲染页面(走web路由、靠session维持登录)
这种场景完全不需要调用api守卫,直接用默认的web守卫获取登录用户即可,推荐用Laravel内置的快捷方法,写法更简洁:
{{-- auth()->id()可以直接取当前登录用户ID,无需先实例化user对象 --}} <a href="/admin/users/edt/{{ auth()->id() }}" class="nav-item dropdown-item">Profile</a>
如果页面允许未登录用户访问,建议加一层登录判断,避免未登录时链接出现空值:
@auth <a href="/admin/users/edt/{{ auth()->id() }}" class="nav-item dropdown-item">Profile</a> @endauth
- 必须通过JWT api守卫获取用户的场景(比如API接口返回视图、请求会携带合法JWT)
必须先判断api守卫的登录状态,再获取用户ID,从根源避免空值报错:
@auth('api') <a href="/admin/users/edt/{{ auth('api')->id() }}" class="nav-item dropdown-item">Profile</a> @endauth
注意这种写法必须保证请求访问页面时,已经按JWT配置要求携带了合法有效的token,否则依然无法获取到用户数据。
注意不要混用两套认证体系的适用场景:web守卫基于session实现,适合同域服务端渲染的页面;JWT驱动的api守卫是无状态设计,适合前后端分离的接口调用,不要在普通web页面里强行调用api守卫取登录用户。
内容的提问来源于stack exchange,提问作者h na
相关产品推荐
相关产品推荐

