hyperf 系列教程之 hyperf-auth 高级用法
前言
上次写了一个 hyperf-auth
组件,收到许多朋友的反馈和支持,非常感谢大家的支持。今天补充一下关于自定义用户认证的方法。
其实,大部分场景下你都可以通过 hyperf-auth 项目的 README
文档了解到具体如何使用 hyperf-auth
的各种功能,但是关于自定义验证,README
其实只是一笔带过。
下面我们就来了解以下具体如何实现自定义验证。
hyperf-auth 组件的设计思路
由于我本人是个 laravel 爱好者,所以整个组件的设计思路大致是跟 laravel auth
相似的,都有 guard
、user provider
,包括配置方式也是极其相似的,所以,扩展方式也是相似的。
自定义 guard
想要实现一个自己的 guard
非常简单,只要实现 Qbhy\HyperfAuth\AuthGuard
接口即可,而且我抽象了一个 AbstractAuthGuard
继承该抽象类可以减少许多代码,大部分情况下,你只需要实现下面这三个方法即可。
<?php
namespace App\Auth\Guard;
use Qbhy\HyperfAuth\Authenticatable;
use Qbhy\HyperfAuth\Guard\AbstractAuthGuard;
class CustomGuard extends AbstractAuthGuard
{
public function login(Authenticatable $user)
{
// TODO: Implement login() method.
}
public function user(): ?Authenticatable
{
// TODO: Implement user() method.
}
public function logout()
{
// TODO: Implement logout() method.
}
}
该类的构造方法可以注入一些 Hyperf
环境中常用的实例,比如 Request
、Session
。不重写构造函数的情况下,配置文件中的值和 guard 的属性对应关系如下:
$authConfig = [
'default' => [
'guard' => 'session',
'provider' => 'users',
],
'guards' => [
'session' => [
'driver' => Qbhy\HyperfAuth\Guard\SessionGuard::class,
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => \Qbhy\HyperfAuth\Provider\EloquentProvider::class,
'model' => App\Model\User::class, // 需要实现 Qbhy\HyperfAuth\Authenticatable 接口
],
];
/** @var SessionGuard $guard */
var_dump($guard->name === 'session'); // true
var_dump($guard->config === $authConfig['guards']['session']); // true 对应gaurds里面的value值
var_dump($guard->userProvider); // 对应的UserProvider实例
当然,你也可以重写构造函数,用以注入你需要用到的实例,或者设置通过自定义配置创建的实例,下面用 JwtGuard
构造函数举例
/** @var JWTManager */
protected $jwtManager;
/** @var RequestInterface */
protected $request;
/**
* JwtGuardAbstract constructor.
*/
public function __construct(
array $config,
string $name,
UserProvider $userProvider,
RequestInterface $request
) {
parent::__construct($config, $name, $userProvider);
$this->jwtManager = new JWTManager($config);
$this->request = $request;
}
自定义 user
有时候可能会给其他模型做认证功能,比如商家认证, 假设我们有 App\Model\Merchant
模型类,想要给商家加上登录认证功能,只需要实现 Qbhy\HyperfAuth\Authenticatable
接口即可。
<?php
declare (strict_types=1);
namespace App\Model;
use Hyperf\DbConnection\Model\Model;
use Qbhy\HyperfAuth\Authenticatable;
/**
*/
class Merchant extends Model implements Authenticatable
{
public static function retrieveById($key): ?Authenticatable
{
// TODO: Implement retrieveById() method.
}
public function getId()
{
// TODO: Implement getId() method.
}
}
通常情况下你只需要实现上面两个方法即可,如果你用来做授权字段就是主键的话,甚至直接使用 Qbhy\HyperfAuth\AuthAbility
这个 trait
就可以了,但是如果你用来做授权的是其他字段,比如 token
的话,就得自己实现这俩方法了
class Merchant extends Model implements Authenticatable
{
use AuthAbility;
}
自定义 UserProvider
大部分情况下,开发者只需要定义模型并按照上面的方法实现 Authenticatable
接口就够用了,包括自定义数据源。如果你要实现更为复杂的自定义用户功能,这时候就需要自定义 UserProvider
了。你需要实现 Qbhy\HyperfAuth\UserProvider
接口。跟 自定义 guard
类似,我同样提供了一个抽象类,直接继承自这个抽象类即可,构造函数会传入 $name
、$config
,具体例子可以参考以下代码。
<?php
declare(strict_types=1);
namespace Qbhy\HyperfAuth\Provider;
use Qbhy\HyperfAuth\Authenticatable;
class EloquentProvider extends AbstractUserProvider
{
public function retrieveByCredentials($credentials)
{
return call_user_func_array([$this->config['model'], 'retrieveById'], [$credentials]);
}
public function validateCredentials(Authenticatable $user, $credentials): bool
{
return $user->getId() === $credentials;
}
}
该类同样允许重写构造函数注入你想要的实例
结语
至此,你已经学会了自定义 hyperf-auth
的相关用法了,其实用法还是和 laravel auth
差不多的,如果还有不懂的地方可以添加 QQ群: 873213948 向我提问。
上一篇: Spark架构与作业执行流程简介
下一篇: Spark核心原理 - 作业执行