php lumen auth,学习 Lumen 用户认证 (一)
好久没写 PHP 代码了,尤其是 Lumen,我是 Lumen 的忠实用户,自从面世开始,我就将 Lumen 作为我 API 的主要框架使用。
但说到 API,不得不说的一个概念:「前后端分离」,现在越来越多的团队都采用前后端分离,彻底解放出前端的优势,也让后台更加集中于数据的输出。关于这方面的讨论,不在这里讨论了,可以参考一些文章深入研究:
正因为有了前后端分离,后台关注于接口 API 的输出,当时 Lumen 的出现,就是为 RESTful API 而生的:
Decidedly Laravel. Delightfully Minimal.
Lightning fast micro-services and APIs delivered with the elegance you expect.
将 Lumen 作为接口框架使用,不得不解决一个核心问题:如何对访问者进行「认证」。
用户认证
Lumen 虽然与 Laravel 使用了相同的底层类库实现,但是因 Lumen 面向的是无状态 API 的开发,不支持 session,所以默认的配置不同。Lumen 必须使用无状态的机制来实现,如 API 令牌(Token)。
我们看看 Lumen 官网提供的例子:
use Illuminate\Http\Request;
$app->get('/post/{id}', ['middleware' => 'auth', function (Request $request, $id) {
$user = Auth::user();
$user = $request->user();
//
}]);
其中使用了中间件:'middleware' => 'auth',我们看看 auth 中间件函数:
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);
关联的是 Authenticate 类,我们看 Authenticate 的 handle 函数:
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
return $next($request);
}
首先会判断$this->auth->guard($guard)->guest()。我们继续跟进代码到 AuthManager 中:
/**
* Attempt to get the guard from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
*/
public function guard($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return isset($this->guards[$name])
? $this->guards[$name]
: $this->guards[$name] = $this->resolve($name);
}
默认传入的 $name = null,所以我们看看 $this->getDefaultDriver():
/**
* Get the default authentication driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['auth.defaults.guard'];
}
这就到了默认的配置 config 中了:
从 Lumen 源代码中可以看出 Lumen 的默认认证方式「api」。
我们再来看看 Laravel 的默认认证方式:
Laravel 默认采用「web」方式,而 web 方式是使用 session 来进行用户认证。这也就很好的说明了 Lumen 的无状态性。
接着我们需要明白 Lumen 如何通过「api」来进行用户认证的。
AuthServiceProvider 存放在 app/Providers 文件夹中,此文件中只有一个 Auth::viaRequest 调用。viaRequest 会在系统需要认证的时候被调用,此方法接受一个匿名函数传参,在此匿名函数内,你可以任意的解析 AppUser 并返回,或者在解析失败时返回 null,如:
/**
* Boot the authentication services for the application.
*
* @return void
*/
public function boot()
{
// Here you may define how you wish users to be authenticated for your Lumen
// application. The callback which receives the incoming request instance
// should return either a User instance or null. You're free to obtain
// the User instance via an API token or any other method necessary.
$this->app['auth']->viaRequest('api', function ($request) {
if ($request->input('api_token')) {
return User::where('api_token', $request->input('api_token'))->first();
}
});
}
我们来看看 viaRequest 函数:
/**
* Register a new callback based request guard.
*
* @param string $driver
* @param callable $callback
* @return $this
*/
public function viaRequest($driver, callable $callback)
{
return $this->extend($driver, function () use ($callback) {
$guard = new RequestGuard($callback, $this->app['request'], $this->createUserProvider());
$this->app->refresh('request', $guard, 'setRequest');
return $guard;
});
}
这里关键的是 RequestGuard,这个类的核心函数:
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// 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;
}
return $this->user = call_user_func(
$this->callback, $this->request, $this->getProvider()
);
}
这个是判断是否获取用户信息,主要是调用callback 函数,而这个函数就是我们从 viaRequest 传入的:
function ($request) {
if ($request->input('api_token')) {
return User::where('api_token', $request->input('api_token'))->first();
}
}
而这只是举一个验证用户的例子,判断请求是否传入 api_token参数,并通过 User Model 直接匹配查找获取 User or null。
当然在实际开发中,我们不能只是简单的获取 api_token直接关联数据库查找用户信息。
在 API 开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证: JWT 和 OAuth2。
下一步
当前只是对 Lumen 的「用户认证」进行简单的了解,下一步通过对 「JWT」的学习,来看看如何利用 JWT 来有效的用户认证,更加安全的保障接口信息被有效的用户访问。
附:
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON 的开放标准 (RFC 7519)。该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。
「未完待续」
coding01 期待您继续关注
php lumen auth,学习 Lumen 用户认证 (一)相关推荐
- 「Django」rest_framework学习系列-用户认证
用户认证: 1.项目下utils文件写auth.py文件 from rest_framework import exceptions from api import models from rest_ ...
- laravel auth.php,Laravel 用户认证 Auth
很多应用是需要登陆后才能操作,Laravel提供了一个auth工具来实现用户的认证功能.并且有一个config/auth.php来配置auth工具.大概看一下auth工具的常用方法 Auth::che ...
- Juniper防火墙之图解用户认证
今天正好学习到Juniper防火墙中的用户认证,那么今天就带大家来看看Juniper防火墙的用户认证. Juniper防火墙的用户分类: 1.Admin User:管理员用户 2.Auth User: ...
- Java-SpringBoot:用户认证(Authentication)和用户授权(Authorization)
Java-SpringBoot-2 学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV1PE411i7CV 学习文档: 微信公众号 狂神说 –htt ...
- 搭建nginx服务、nginx的升级安装、Nginx配置文件的解析、web页面用户认证
一,Nginx安装 1.安装nginx # yum -y install gcc pcre-devel openssl-devel //安装 ...
- LINUX 用户认证
问题 沿用练习一,通过调整Nginx服务端配置,实现以下目标: 1.访问Web页面需要进行用户认证 2.用户名为:tom,密码为:123456 2.2 方案 模板配置文件框架如下: 1.[root@p ...
- php lumen auth,Lumen实现用户注册登录认证
Lumen实现用户注册登录认证 前言 Lumen是一个基于Laravel的微框架,号称是以速度为生.截用Lumen官网的一段,号称是比silex和slim还要快. 本文将用Lumen来实现一个完整的用 ...
- lumen 框架学习
路由 基本使用 # 直接返回信息或简单处理,一般很少用这个 $app->get('/', function() {return 'Hello World'; });# 携带参数 $app-> ...
- Django框架(十八)—— auth框架:用户登录、注册、认证
auth模块 一.什么是author模块 Auth模块是Django自带的用户认证模块,可以实现包括用户注册.用户登录.用户认证.注销.修改密码等功能.默认使用 auth_user 表来存储用户数据. ...
最新文章
- 树莓派4视频输出接口_树莓派第四代来啦!4G内存、支持双屏4K输出和H265硬解
- 大学生python实验心得体会_大学生实验心得体会精选例文【三篇】
- Spring概念理解
- 【2016年第6期】中国科学院科学数据云建设与服务
- [agc011e]increasing numbers
- GitHub 的“封神”之路!
- c语言中memset_C中的memset()
- 设计分享 | STM32F103RCT6利用ULN2003驱动步进电机正反转
- python turtle渐变色_Python : turtle色彩控制实例详解
- CPAN | 配置阿里源
- 苹果M1电脑上还能运行Windows吗?苹果:留了路,看微软
- PYNQ系列学习(三)|pynq与zynq对比(二)
- 翻译:SQL Server 2005中的覆盖索引
- 程序员提升逼格技巧汇总
- node.js 安装,详细步骤教程
- VScode+keil插件-取代keil开发不要太爽了
- MOT:Metrics MOTA
- 压力传感器压力变送器如何选型
- Spark Core:Scala单词计数
- Class Agnostic的物体检测/分割