Laravel9中PHP-Open-Source-Saver/jwt-auth刷新令牌报错解决方案
问题
在Laravel 9(PHP 8.1)环境下开发API,实现JWT刷新令牌逻辑时,使用官方示例代码出现两个Intelephense错误:
Undefined method 'factory'.intelephense(1013)Undefined method 'refresh'.intelephense(1013)
此前使用旧版本tymondesigns/jwt-auth库时无此类问题,需明确错误原因及正确的刷新令牌实现方式。
示例代码如下:
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; class AuthController extends Controller { /** * Create a new AuthController instance. * * @return void */ public function __construct() { $this->middleware('auth:api', ['except' => ['login']]); } /** * Get a JWT via given credentials. * * @return \Illuminate\Http\JsonResponse */ public function login() { $credentials = request(['email', 'password']); if (! $token = auth()->attempt($credentials)) { return response()->json(['error' => 'Unauthorized'], 401); } return $this->respondWithToken($token); } /** * Get the authenticated User. * * @return \Illuminate\Http\JsonResponse */ public function me() { return response()->json(auth()->user()); } /** * Log the user out (Invalidate the token). * * @return \Illuminate\Http\JsonResponse */ public function logout() { auth()->logout(); return response()->json(['message' => 'Successfully logged out']); } /** * Refresh a token. * * @return \Illuminate\Http\JsonResponse */ public function refresh() { return $this->respondWithToken(auth()->refresh()); } /** * Get the token array structure. * * @param string $token * * @return \Illuminate\Http\JsonResponse */ protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => auth()->factory()->getTTL() * 60 ]); } }
错误原因
这两个错误本质是Intelephense无法识别JWT Auth扩展的auth()门面方法,核心原因有两点:
- 适配Laravel 9的新版
tymondesigns/jwt-auth调整了auth()门面的方法封装逻辑,旧版直接通过auth()->refresh()、auth()->factory()调用的方式,在新版中缺乏完整的类型提示,导致IDE静态分析无法识别方法。 - Intelephense依赖准确的类型注解或扩展包定义来识别方法,若JWT Auth的类型定义未被IDE正确加载,就会触发此类未定义方法提示。
正确实现方式
方法1:明确指定JWT Guard实例
通过类型声明获取JWT Guard实例,让IDE能正确识别方法:
// 在控制器顶部导入JWT Guard接口 use Tymon\JWTAuth\Contracts\JWTGuard; // 替换auth()调用为带类型声明的实例 protected function respondWithToken($token) { /** @var JWTGuard $auth */ $auth = auth('api'); return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => $auth->factory()->getTTL() * 60 ]); } public function refresh() { /** @var JWTGuard $auth */ $auth = auth('api'); return $this->respondWithToken($auth->refresh()); }
方法2:生成IDE辅助文件
通过laravel-ide-helper工具自动生成扩展包的类型注解,解决Intelephense识别问题:
- 安装依赖:
composer require --dev barryvdh/laravel-ide-helper - 生成辅助文件:
php artisan ide-helper:generate - 生成门面注解:
php artisan ide-helper:meta
方法3:直接使用JWTAuth门面
导入JWTAuth门面替代auth(),直接调用方法:
use Tymon\JWTAuth\Facades\JWTAuth; // 刷新令牌方法 public function refresh() { return $this->respondWithToken(JWTAuth::refresh()); } // 返回令牌信息方法 protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => JWTAuth::factory()->getTTL() * 60 ]); }
修正后的完整AuthController代码
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; use Tymon\JWTAuth\Contracts\JWTGuard; class AuthController extends Controller { /** * Create a new AuthController instance. * * @return void */ public function __construct() { $this->middleware('auth:api', ['except' => ['login']]); } /** * Get a JWT via given credentials. * * @return \Illuminate\Http\JsonResponse */ public function login() { $credentials = request(['email', 'password']); /** @var JWTGuard $auth */ $auth = auth('api'); if (! $token = $auth->attempt($credentials)) { return response()->json(['error' => 'Unauthorized'], 401); } return $this->respondWithToken($token); } /** * Get the authenticated User. * * @return \Illuminate\Http\JsonResponse */ public function me() { return response()->json(auth()->user()); } /** * Log the user out (Invalidate the token). * * @return \Illuminate\Http\JsonResponse */ public function logout() { auth()->logout(); return response()->json(['message' => 'Successfully logged out']); } /** * Refresh a token. * * @return \Illuminate\Http\JsonResponse */ public function refresh() { /** @var JWTGuard $auth */ $auth = auth('api'); return $this->respondWithToken($auth->refresh()); } /** * Get the token array structure. * * @param string $token * * @return \Illuminate\Http\JsonResponse */ protected function respondWithToken($token) { /** @var JWTGuard $auth */ $auth = auth('api'); return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => $auth->factory()->getTTL() * 60 ]); } }
内容的提问来源于stack exchange,提问作者Wilton Neves Aguiar
相关产品推荐
相关产品推荐

