Laravel 5.5类型错误:validateCredentials()参数类型不匹配求助
我来帮你排查并解决这个登录时的类型错误,先看看你的代码和错误详情:
你的代码片段
LoginController(Auth目录下)
namespace App\Http\Controllers\Auth; use App\Model\Admin; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Redirect; use Hash; use Auth; use DB; use App\Model\UserAdmin; class LoginController extends Controller { use AuthenticatesUsers; public function __construct() { $this->middleware('guest')->except('logout'); } public function doLogin(Request $request) { $userdata = array( 'email' => Input::get('email'), 'password' => Input::get('password'), 'status' => '1', ); if (Auth::guard('admin')->attempt($userdata)) { return Redirect::intended('/administrator/dashboard')->with('successMessage', 'You have successfully logged in.'); } } }
UserAdmin模型(app/Model目录下)
namespace App\Model; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; use Illuminate\Foundation\Auth\User as Authenticatable; use Config; class UserAdmin extends Authenticatable { protected $table = 'adminusers'; public $timestamps = false; protected $fillable = ['firstName', 'lastName', 'email', 'company', 'website']; public function __construct() { parent::__construct(); // Don't forget this, you'll never know what's being done in the constructor of the parent class you extended } }
抛出的错误
Type error: Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Model\UserAdmin given, called in /var/www/html/XXXXXX/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php on line 379
问题根源
这个错误看起来矛盾,但核心原因是你的admin Guard没有正确关联到实现了Authenticatable接口的模型。虽然你的UserAdmin继承了Authenticatable(它已经实现了Illuminate\Contracts\Auth\Authenticatable接口),但Laravel的Auth系统没识别到这一点,大概率是配置文件的问题。
分步解决方案
1. 修正Auth配置文件
打开config/auth.php,确保guards和providers部分的配置正确关联到你的UserAdmin模型:
'guards' => [ // 保留默认的web guard,添加admin guard 'admin' => [ 'driver' => 'session', 'provider' => 'admins', // 这个provider名称要和下面的对应 ], ], 'providers' => [ // 保留默认的users provider,添加admins provider 'admins' => [ 'driver' => 'eloquent', 'model' => App\Model\UserAdmin::class, // 必须是模型的完整命名空间 ], ],
2. 清除配置缓存
Laravel会缓存配置文件,修改后必须清除缓存才能生效:
php artisan config:clear php artisan cache:clear
3. 可选:优化LoginController代码
Laravel 5.5里推荐直接使用请求对象获取输入,代替Input::get(),让代码更规范:
// 替换原来的userdata赋值 $userdata = [ 'email' => $request->email, 'password' => $request->password, 'status' => '1', ];
4. 检查模型继承的正确性
确认你的UserAdmin模型确实继承了Illuminate\Foundation\Auth\User(也就是你写的Authenticatable),这个父类已经帮你实现了Authenticatable接口,所以只要继承正确,模型就符合要求。
为什么这样能解决?
当你调用Auth::guard('admin')->attempt()时,Laravel会根据config/auth.php里的配置找到对应的Provider,再加载指定的模型。如果配置里的模型路径错误,或者Guard和Provider没有正确关联,系统就会加载错误的类(或者无法识别模型的接口实现),从而抛出类型错误。修正配置并清除缓存后,系统就能正确识别你的UserAdmin模型,验证也就正常工作了。
内容的提问来源于stack exchange,提问作者Niladri Banerjee - Uttarpara

