老司机带你领悟 Laravel 之授权系统

前言

Laravel之授权

这篇博文主要是带大家了解laravel的授权系统,依照惯例,我会忽略一些细节,大家自己有兴趣的话,自行阅读。如果你仔细阅读了我之前写的,我觉得读懂这篇博文,简直不要太容易。

准备

在阅读这篇博客之前,你一定要阅读《老司机带你深入理解 Laravel 之 Facade》,这是必须的。

Auth Facade

我们的分析从Illuminate\Support\Facades\Auth开始,下面是它的定义:

Laravel之授权

我们搜索整个laravel项目,搜索关键词'Auth',在Illuminate\Auth\AuthServiceProvider中可以看到:

Laravel之授权

这里给Auth注册了一个单例,也就是说所有对Illuminate\Support\Facades\Auth的操作实际上就是在操作Illuminate\Auth\AuthManager类的实例对象,下面我以Auth::guard()方法给大家分析,大家应该操作过这个方法吧。

Laravel之授权

这里的getDefaultDriver返回默认的驱动,我们来看看:

Laravel之授权

这里直接读取app/auth.php文件的defaults下的guard,打开我的配置文件,可以看到:

Laravel之授权

返回到guard方法中,继续调用resolve方法,如下:

Laravel之授权

这里的getConfig方法会读取到下面的配置:

Laravel之授权

返回到resolve方法中:

Laravel之授权

从这里的分析可以看到createSessionDriver方法被调用
Laravel之授权

首先这里的createUserProvider方法被调用,它的$config['provider']为users,我们来看一下这个方法:

Laravel之授权

这里的$config就是:

Laravel之授权

因为drivereloquent,所以这里会调用createEloquentProvider方法:

Laravel之授权

也就是说createEloquentProvider方法返回了一个\Illuminate\Auth\EloquentUserProvider类的对象,我们再次回到createSessionDriver方法中:

Laravel之授权

这里创建了一个SessionGuard类的对象,至此resolve方法解析完毕,返回到guard方法中,如果你需要验证这一点的话,你可以在任何一个控制器中,运行dd(Auth::guard())会返回一个SessionGuard类的对象。

当我们授权用户的时候,我们会使用到如下所示的代码:

/*** 
@var  $guard SessionGuard
* **/
$guard = Auth::guest();
$guard->attempt(["name"=>"DennisRitche","password"=>"Goodbyte World"]);

根据上面的分析,SessionGuard类的attempt方法被调用:

Laravel之授权

这里的provider就是我们之前创建的Illuminate\Auth\EloquentUserProvider类对象,我们看下它的retrieveByCredentials方法:

Laravel之授权

上面的createModel实际上就是创建一个我们之前配置的类的对象:

Laravel之授权

retrieveByCredentials方法根据我们的用户名从数据库查询出对应的记录,返回到SessionGuard类的attempt
方法中,继续调用如下代码:

Laravel之授权

方法hasValidCredentials作用就是验证我们提交的密码是否和数据库里面的密码是相等(数据库里面的密码加密过,所以在比较之前,用户提交的密码也需要经过加密步骤),这部分代码很简单,这里略过,如果hasValidCredentials返回true,表示验证通过,此时login方法被调用:

Laravel之授权

首先调用updateSession方法会把当前登陆的用户标识写入到session中:

Laravel之授权

接下来调用setUser方法,如下:

Laravel之授权

这里记录了当前登录的用户,以后每次Auth::user()调用都会获取到这个用户实例。

总结

上面简要的分析了Laravel的授权系统,代码本身并不复杂,我也是给大家介绍了一下分析的思路,很多细节,需要自己去分析和理解。我有一个QQ群,有兴趣的可以加一下:

本作品采用《CC 协议》,转载必须注明作者和本文链接
微信:okayGoHome
本帖由系统于 4年前 自动加精
Dennis_Ritchie
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 9

mark.以后再看.

4年前 评论

写的很棒,我感觉只要真正明白了 服务容器 和 服务提供者,源码看起来就感觉容易了很多。

4年前 评论
nfangxu

https://github.com/nfangxu/hyperf-http-aut...

邀请大佬一起完善一下这个包 :joy: :joy: :joy:

4年前 评论
ShiKi

mark

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!