默认的auth中间件做用户认证,每次都会查询数据库吗?
想了解一下laravel默认的认证流程,查看了源码,auth.php中默认的guard是web,查看它的配置,driver为session,provider是App\User
eloquent,于是猜想,第一次登录认证应该是通过provider查数据库,并将用户信息放入session,之后的请求都是从session获得用户信息,如果session中没有就说明没有登录.
为了验证我的猜想,继续查看源码,中间件中的认证是在Illuminate\Auth\Middleware\Authenticate
的$this->auth->authenticate()
这一句,其中auth默认是Illuminate\Auth\AuthManager
,它的authenticate()
方法是用的__call
,实际调用的是SessionGuard
中的authenticate()
,这其中主要的认证就是下面的代码:
`
public function user()
{
if ($this->loggedOut) {//已退出就返回空,所以认证失败
return;
}
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {//同一个请求,如果已验证过,就不用再次请求.
return $this->user;
}
$id = $this->session->get($this->getName());//从session中获取用户id
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if (! is_null($id)) {
if ($user = $this->provider->retrieveById($id)) {//从数据库获取用户
$this->fireAuthenticatedEvent($user);
}
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller)) {
$user = $this->getUserByRecaller($recaller);
if ($user) {
$this->updateSession($user->getAuthIdentifier());
$this->fireLoginEvent($user, true);
}
}
return $this->user = $user;
}
`
从上面代码可以看出来,其实session中存的只是user表的id,如果我想获得用户的信息,每次用Auth::user()的使用,其实都是走数据库的.
以上是我的分析,不知道对不对,如果是这样,性能会不会很差啊?
8 Comments
session的作用就是记住用户状态 登录之后从session里面取
@nonfu#170 这个状态只是存的用户的Id吗? 如果我的页面中使用Auth::user(),是不是每一次请求都是查数据库了?
@mygoodidea#171 刚看了下代码 当前请求不会 新的请求都会取数据库 这里如果考虑到性能问题可以优化下
@nonfu#173 所以,比如我用默认的auth中间件来判断用户的登录状态,是不是每次刷新页面都会查数据库?好像有点坑啊.
学院君,你的后台判断管理员登陆状态也是用的这个吗?每次管理员信息都查数据库
@mygoodidea#174 可以监听用户登录事件将用户信息存到自定义session 用户退出时将这个session移除 期间都可以从这个session获取数据
@nonfu#175 明白了,谢谢了,只能自己写一个auth的中间件了
@mygoodidea#176 框架提供的东西有时候更多考虑的是易于上手 快速实现功能 至于性能需要我们根据业务不断做调整和优化
@nonfu#177 确实如此,谢谢你的回答:smile: