Laravel 5.4多表JWT认证问题:用户表正常司机表无法认证
我之前也碰到过Laravel多模型JWT认证的坑,结合你用的Laravel 5.4和tymon/jwt-auth 1.0.0-rc.2版本,咱们一步步排查Driver认证失效的问题:
1. 先确认config/auth.php的守卫&提供者配置是否正确
这是双模型认证的核心配置,一定要确保Driver的守卫和提供者对应正确:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], // 新增Driver专属守卫 'driver-api' => [ 'driver' => 'jwt', 'provider' => 'drivers', // 关联下面的drivers提供者 ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], // 新增Driver模型提供者 'drivers' => [ 'driver' => 'eloquent', 'model' => App\Driver::class, // 指向你的Driver模型 ], ],
2. 检查Driver模型的JWT实现是否到位
jwt-auth 1.0要求模型必须实现JWTSubject接口,同时要确保密码字段是哈希存储的:
namespace App; use Illuminate\Database\Eloquent\Model; use Tymon\JWTAuth\Contracts\JWTSubject; use Tymon\JWTAuth\Traits\JWTSubject as JWTTrait; class Driver extends Model implements JWTSubject { // 用这个trait可以自动实现接口的两个方法,省得自己写 use JWTTrait; // 如果你需要在token里加入自定义字段(比如区分用户类型),可以手动实现方法: /* public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return ['user_type' => 'driver']; } */ // 务必设置可填充字段,尤其是email和password protected $fillable = ['email', 'password', 'name', ...]; }
⚠️ 注意:Driver表的密码必须用Hash::make()存储,不能存明文!
3. 登录逻辑要指定Driver专属守卫
很多人踩坑就是因为登录时没指定守卫,默认用了User的api守卫。示例登录控制器代码:
namespace App\Http\Controllers\API; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Tymon\JWTAuth\Facades\JWTAuth; use Illuminate\Support\Facades\Validator; class DriverAuthController extends Controller { public function login(Request $request) { $validator = Validator::make($request->all(), [ 'email' => 'required|email', 'password' => 'required|string', ]); if ($validator->fails()) { return response()->json($validator->errors(), 400); } // 关键:指定使用driver-api守卫验证凭证 $credentials = $request->only('email', 'password'); if (!$token = JWTAuth::guard('driver-api')->attempt($credentials)) { return response()->json(['error' => '账号或密码错误'], 401); } return $this->respondWithToken($token); } protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => JWTAuth::guard('driver-api')->factory()->getTTL() * 60 ]); } // 刷新token也要指定守卫 public function refresh() { return $this->respondWithToken(JWTAuth::guard('driver-api')->refresh()); } }
4. 路由要绑定Driver守卫的中间件
保护Driver的API路由时,中间件必须指定auth:driver-api,而不是默认的auth:api:
// 无需认证的登录/刷新路由 Route::post('driver/login', 'API\DriverAuthController@login'); Route::post('driver/refresh', 'API\DriverAuthController@refresh')->middleware('auth:driver-api'); // 需要Driver认证的路由组 Route::group(['prefix' => 'driver', 'middleware' => 'auth:driver-api'], function () { Route::get('/profile', 'API\DriverController@getProfile'); // 其他Driver专属接口... });
5. 最后排查几个常见坑
- 清除配置缓存:执行
php artisan config:clear,Laravel 5.4的配置缓存很容易导致新守卫不生效 - 确认.env里的
JWT_SECRET已生成:执行php artisan jwt:secret生成密钥,两个模型共用这个密钥没问题 - 查看日志:如果还是不行,去
storage/logs/laravel.log里找具体错误信息,比如是模型找不到、凭证不匹配还是守卫配置错误
内容的提问来源于stack exchange,提问作者Yousef Altaf
相关产品推荐
相关产品推荐

