有点疑问,也是分享,希望大家进来讨论一下,关于使用 Auth::attempt ($credentials) 验证报错的问题!
我使用 Auth::attempt($credentials) 掩着那个登录时 ,当我的 User模型为下面这种写法时,
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
}
在点击登录提交数据后会报 以下
Type error: Argument 1 passed to EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Models\User given, called in /home/vagrant/Code/Laravel/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php on line 379
这样的错误!
当我将User模型文件修改成以下,这样就能够正常登录并跳转到个人页面
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
}
那么继承Model 和 继承 Authenticatable 有什么区别呢,继承Authenticatable的作用是什么呢?为什么继承Model会报错呢?现在问题已经解决但是还是不清楚!
高认可度评论:
Laravel的封装非常非常精细,代码可重用性非常高,用起来很爽,但这也导致了解它的运作原理变得很困难。从Auth::Attempt()展开分析,绕了好远的路。
我们来看看
Authenticatable
是什么,然后顺着Auth::attempt()
的调用过程,看看它依赖了Authenticatable
的什么东东。User.php
代码片段:Authenticatable
,即Illuminate\Foundation\Auth\User
,其代码如下:以上,User类继承Model,并实现了三个接口,而三个接口分别由三个trait一一实现,而其中
Authenticatable
是Auth::attempt()
调用过程中到的,有关这个报错的。接下来,我们分析一下
Auth::attempt()
调用流程:attempt()
位于Illuminate\Auth\SessionGuard
(Auth怎么调用到attempt()还可以分析一长篇,这里先看attemp()的实现),attempt()
代码片段:调用到的方法:
$this->provider是从配置文件读取进来的驱动,这里为Eloquent, 所以validateCredentials是属于 Illuminate\Auth\EloquentUserProvider下的,代码:
这里重点看一下注入的类
UserContract
。UserContract
是 Illuminate\Contracts\Auth\Authenticatable的别名,仅仅是一个接口,其实现位于Authenticatable这个trait。前面这个trait在Illuminate\Foundation\Auth\User
引入,然后User模型继承了这个类,所以这里就和attempt()方法搭上关系了,UserContract
的代码片段如下:attempt()
中有这一行:$user = $this->provider->retrieveByCredentials($credentials);
,validateCredentials
的$user变量是从这里产生的。retrieveByCredentials
方法代码如下:重点看
$query = $this->createModel()->newQuery();
这一行。这里生产了类的实例:
这里返回的$user为什么是UserContract类,我也还没搞清楚。有空再慢慢分析。
你看一下 Authenticatable 这个类的代码不就知道了吗?
Laravel的封装非常非常精细,代码可重用性非常高,用起来很爽,但这也导致了解它的运作原理变得很困难。从Auth::Attempt()展开分析,绕了好远的路。
我们来看看
Authenticatable
是什么,然后顺着Auth::attempt()
的调用过程,看看它依赖了Authenticatable
的什么东东。User.php
代码片段:Authenticatable
,即Illuminate\Foundation\Auth\User
,其代码如下:以上,User类继承Model,并实现了三个接口,而三个接口分别由三个trait一一实现,而其中
Authenticatable
是Auth::attempt()
调用过程中到的,有关这个报错的。接下来,我们分析一下
Auth::attempt()
调用流程:attempt()
位于Illuminate\Auth\SessionGuard
(Auth怎么调用到attempt()还可以分析一长篇,这里先看attemp()的实现),attempt()
代码片段:调用到的方法:
$this->provider是从配置文件读取进来的驱动,这里为Eloquent, 所以validateCredentials是属于 Illuminate\Auth\EloquentUserProvider下的,代码:
这里重点看一下注入的类
UserContract
。UserContract
是 Illuminate\Contracts\Auth\Authenticatable的别名,仅仅是一个接口,其实现位于Authenticatable这个trait。前面这个trait在Illuminate\Foundation\Auth\User
引入,然后User模型继承了这个类,所以这里就和attempt()方法搭上关系了,UserContract
的代码片段如下:attempt()
中有这一行:$user = $this->provider->retrieveByCredentials($credentials);
,validateCredentials
的$user变量是从这里产生的。retrieveByCredentials
方法代码如下:重点看
$query = $this->createModel()->newQuery();
这一行。这里生产了类的实例:
这里返回的$user为什么是UserContract类,我也还没搞清楚。有空再慢慢分析。
感谢大佬分享,最起码错在哪是知道了!