在中间件实现用户认证,并在控制器中获取

需求

在中间件中进行用户认证后,在控制器中可以通过 $this->user()的方法拿到用户

解决

创建中间件 UserAuth

<?php

declare(strict_types=1);

namespace App\Middleware\Auth;

use App\Model\User;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Hyperf\Utils\Context;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

class UserAuth implements MiddlewareInterface
{
    protected $container;

    protected $request;

    protected $response;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // 处理 get post 从中拿取名字为 ak 的
        $key = $this->pcs_method_getKey("ak", $request);
        if ($key) {
            // 你用户的判断方式
            $user = User::where('api_token', '=', $key)->first();
            if ($user) {
                $request = $request->addParserBody('user', $user);
                // https://doc.hyperf.io/#/zh/middleware/middleware?id=%e5%85%a8%e5%b1%80%e6%9b%b4%e6%94%b9%e8%af%b7%e6%b1%82%e5%92%8c%e5%93%8d%e5%ba%94%e5%af%b9%e8%b1%a1
                // 更改上下文
                Context::set(ServerRequestInterface::class, $request);
                return $handler->handle($request);
            }
        }
        // 未通过
        return $this->response->json([
            'code' => 401,
            'msg' => 'auth_no_pass',
        ]);
    }

    protected function pcs_method_getKey(string $key, ServerRequestInterface $request)
    {
        switch ($request->getMethod()) {
            case "GET":
                return isset($request->getQueryParams()[$key]) ? $request->getQueryParams()[$key] : null;
                break;

            case "POST":
                return isset($request->getParsedBody()[$key]) ? $request->getParsedBody()[$key] : null;
                break;
        }
        return false;
    }
}

在你的基础 Controller 加入

<?php

namespace App\Controller;

use App\Model\User;
use Hyperf\Di\Annotation\Inject;

class AuthController extends BaseController
{
    public function user(): ?User
    {
        return $this->request->getParsedBody()['user'] ?? null;
    }
}

然后你就可以在继承了 AuthController 的控制器中 通过调用 $this->user() 调用

感谢

Hyperf 官方QQ群:862099724 内各位大佬的帮助 此方法来自 群内 郭** 的分享

thanks.
讨论数量: 1

感谢分享,文章写得很不错!但是代码如果能跑一下fixer可能会更规范一些!

5年前 评论

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