很多小伙伴在使用API与后端通讯是都在想如何更安全高效的鉴权
那么可以在hyperf的自定义中间件中加入jwt完成接口的鉴权
文章开始
JWT 鉴权的重要性主要体现在以下几个方面:
-
安全性:JWT 使用数字签名或加密机制来保证传输过程中的安全性,确保传输的信息不会被篡改或伪造。
-
可扩展性:JWT 可以轻松地与其他身份验证和授权机制集成,例如 OAuth、OpenID 等。
-
无状态性:JWT 本身不需要存储在服务器端,因此可以轻松地扩展应用程序,而无需担心服务器端的负载问题。
-
可定制性:JWT 可以携带各种自定义声明,例如用户 ID、角色、权限等,使得开发者能够根据具体的业务需求进行定制。
1.创建中间件
<?php
declare(strict_types=1);
namespace App\Middleware;
use App\Exception\UnauthorizedException;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Utils\Context;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class JwtAuthMiddleware implements MiddlewareInterface
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var RequestInterface
*/
protected $request;
/**
* @var ResponseInterface
*/
protected $response;
public function __construct(ContainerInterface $container, RequestInterface $request, ResponseInterface $response)
{
$this->container = $container;
$this->request = $request;
$this->response = $response;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): PsrResponseInterface
{
$token = $this->request->header('Authorization');
if (!$token) {
throw new UnauthorizedException('Token not found');
}
$jwt = $this->container->get(\HyperfExt\Jwt\Jwt::class);
$payload = $jwt->getParser()->parse((string) $token);
if (!$jwt->verify($payload)) {
throw new UnauthorizedException('Unauthorized');
}
$user = $jwt->getUser($payload['sub']);
if (!$user) {
throw new UnauthorizedException('User not found');
}
Context::set('user', $user);
return $handler->handle($request);
}
}
上述代码,需要在App目录或对应的应用内创建Middleware文件夹,新建JwtAuthMiddleware.php文件并粘贴此代码,其中需要关注的是 process 方法,这里是通过request中的header('Authorization')字段拿到通讯token,并通过jwt的内建方法快速提取用户ID等信息及过期时间,并通过Content协程上下文进行传递
2.在 config/autoload/middlewares.php 中注册中间件
<?php
declare(strict_types=1);
return [
'http' => [
······其他中间件
\App\Middleware\JwtAuthMiddleware::class,
],
];
这里是注册中间件,加入hyperf的运行流程,方便后续的引用
3.引用中间件去识别用户
这里要注意官方提供了多种方法引用中间件,本篇文章仅简单介绍常用的两种
1.注解引用
通过在控制器声明处注解,如下代码
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\Controller;
use App\Middleware\JwtAuthMiddleware;
use Hyperf\Utils\Context;
/**
* @Controller()
* @Middleware(JwtAuthMiddleware::class)
*/
class UserController
{
/**
* @PostMapping(path="/user/info")
*/
public function info()
{
$user = Context::get('user');
return [
'code' => 0,
'data' => $user,
];
}
}
2.绑定路由注解
在config/routes.php中对指定路由的方法进行鉴权
如下方代码,将路由/member/user/info 的访问用户加入Jwt自建中间件进行鉴权
use App\Middleware\JwtAuthMiddleware;
Router::addGroup(
'/member', function () {
Router::post('/user/info', [\App\Controller\UserController::class, 'info']);
},
['middleware' => [JwtAuthMiddleware::class]]
);
总结
Hyperf 3.0 是一个高性能的 PHP 框架,支持创建中间件并使用 JWT 鉴权去识别用户。
JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在网络应用之间传递声明,以便进行身份验证和授权。JWT 由三部分组成:头部、载荷和签名。在 JWT 的载荷中,可以存储一些与用户相关的信息,例如用户的 ID、用户名等。
将两者相结合,可以打造出性能与安全共存的完美的接口安全方案