当前位置:首页 > Hyperf > 正文内容

Hyperf中间件验证用户登录状态

陈杰3年前 (2020-12-09)Hyperf3921

才开始接触hyperf,就被他惊人的并发处理性能所惊呆了。所以在工作空余之时学习一下hyperf。

今天要学习一下hyperf的中间件的使用。


新建一个中间件,主要功能就是取每次请求的header头里面的uid和token来比对用户是否是正确的登录用户

<?php

declare(strict_types=1);

namespace App\Middleware;

use App\Common\Tools;
use App\Model\User\UserModel;
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 CheckLoginMiddleware implements MiddlewareInterface
{
   use Tools;

   /**
    * @var ContainerInterface
    */
   protected $container;

   public function __construct(ContainerInterface $container)
   {
       $this->container = $container;
   }

   public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
   {
       $uid   = $request->getHeader('uid');
       $token = $request->getHeader('token');

       if (isset($uid) and isset($token) and isset($uid[0]) and isset($token[0])) {


           $user = UserModel::findFromCache($uid[0]);

           if (!isset($user))
               return $this->error('没有找到该用户', 999);

           $user_token = md5($user['token'] . env('APP_KEY'));

           if ($user_token === $token[0]) {

               $request = $request->withAttribute("user", $user);
               Context::set(ServerRequestInterface::class, $request);

               return $handler->handle($request);

           } else {
               return $this->error('登录错误', 999);
           }
       }
       return $this->error('登录参数错误', 999);
   }
}


如果验证通过了,那么把当前的userModel取到的用户模型通过withAttribute方法挂载到request中并传递给后面的controller使用。

这里有一个上下文存储的代码

       Context::set(ServerRequestInterface::class, $request);

在群里争论了很久,加不加这一句又没有影响,有人说没事不用加,框架自动自动协程化了,多个用户并发请求并不会造成代码共用,内存穿透之类的错误,

但是又有人说必须要加,在高并发下会出现甲用户取到乙用户的数据,纠结了很久,查了文档,写得也比较模糊,但是百度了一下,看了看别人写的中间件,貌似都加了,算了,加上吧。

至于好大的并发出出现内容混淆也没测试,加上总之不为过吧,如果官方文档能解释一下就更好了。。


然后就是在我们的路由中使用这个中间件了。

<?php

declare(strict_types=1);

/**
* This file is part of Hyperf.
*
* @link     https://www.hyperf.io
* @document https://hyperf.wiki
* @contact  group@hyperf.io
* @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
*/

use Hyperf\HttpServer\Router\Router;


Router::get('/favicon.ico', function () {
   return '';
});

Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController@index');


Router::addGroup(
   '/v1', function () {

   Router::addRoute(['GET', 'POST'], '/index/home', 'App\Controller\IndexController@home');
   Router::addRoute(['GET', 'POST'], '/map/get_map', 'App\Controller\MapController@get_map');


},
   ['middleware' => [\App\Middleware\CheckLoginMiddleware::class]]
);


至此我们的中间件就可以正常工作了,然后再后面的controller中去取user的取法

$user       = $this->request->getAttribute('user');

这样就直接取到了

扫描二维码至手机访问

扫描二维码推送至手机访问。

版权声明:本文由何烦过虎溪发布,如需转载请注明出处。

转载请注明出处:http://blog.95shouyou.com/?id=19

分享给朋友:

相关文章

Hyperf跨域问题的解决方案

Hyperf跨域的问题解决方案在传统框架中一般来说有两种方案例如在laravel中直接在入口文件index.php中加上允许跨域代码,或者通过nginx反向代理配置在laravel中header(&#...

Hyperf异常类,抛出异常并中断执行

Hyperf异常类,抛出异常并中断执行

在我们的传统的php框架中,我个人习惯代码需要分层的。例如分为 Controller层,Service层,Model层。Controller层就是做个参数接收啊,参数验证之类的事情,然后Service...

Hyperf表单数据验证器

Hyperf表单数据验证器

hyperf虽然基于swoole,但是风格很像laravel,所以上手还是挺快的。记录一下基于hyperf的表单验证器的代码。因为写代码喜欢一把梭,所以太过解耦的验证类就不用了,太麻烦了。简单一点。照...

Hyperf的redis异步队列实战

突发奇想想写一个RTS战略类游戏。RTS战略类游戏核心玩法肯定是有养成啊,比如建筑升级啊,征兵队列啊,之类的,总之就是用户现在点了操作但是拿不到结果,可能要等几十分钟或者更久拿到结果。现在我们来实现以...

Hyperf缓存封装

hyperf官方的缓存文档写得很好,但是对于一个从传统框架比如laravel thinkphp转到这上面来学习的同学就不是很友好了。原理都很好,自动维护缓存,注解缓存这些东西,在我开始学习php的时候...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。