菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
22
0

另类用法 hyperf/session 实现 API token

原创
05/13 14:22
阅读数 959

前期准备

安装 hyperf/session 使用 redis 作为 session 存储

我的做法

把session的id作为 api key,这样登录的时候只要把信息写入session,前端传递id key 进来 就可以调取session里的信息,并且只要把id传递到其他客户端只要相同key也可以调取信息,只要redis里的信息没有过期

一开始遇到的问题

session默认方法是从cookie里拿,有点不方便,前端需要注意 cors 跨域问题然后还要传递cookie。

解决方法

使用 切面切入 Hyperf\Session\SessionManager::parseSessionId 获取id的方法,魔改本方法

以下是我的代码

<?php

declare(strict_types=1);

namespace App\Aspect;

use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Redis\RedisFactory;
use Hyperf\Utils\Str;
use Psr\Container\ContainerInterface;
use Hyperf\Di\Aop\ProceedingJoinPoint;

/**
 * @Aspect
 */
class SessionAspect extends AbstractAspect
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @Inject()
     * @var RequestInterface
     */
    protected $request;

    /**
     * @Inject()
     * @var ConfigInterface
     */
    protected $config;

    /**
     * @Inject()
     * @var StdoutLoggerInterface
     */
    protected $logger;

    /**
     * @var array
     */
    public $classes = [
        'Hyperf\Session\SessionManager::parseSessionId'
    ];

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

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        $priority = $this->config->get('session.options.id_priority');
        $sessionID = null;
        // 默认从 cookie 里获取 ID
        if ($priority['cookie']) {
            $cookies = $this->request->getCookieParams();
            foreach ($cookies as $key => $value) {
                if ($key === $this->getSessionName()) {
                    $sessionID = (string)$value;
                }
            }
        }
        // header 获取id
        if (isset($priority['header'])) {
            if ($this->request->hasHeader($priority['header'])) {
                $sessionID = (string)$this->request->getHeader($priority['header'])[0];
            }
        }
        // url 参数 获取id
        if (isset($priority['get']) && $sessionID === null) {
            $params = $this->request->getQueryParams();
            if ($params && array_key_exists($priority['get'], $params)) {
                $sessionID = (string)$params[$priority['get']];
            }
        }
        if ($sessionID && strlen($sessionID) === 40) {
            $redis = $this->container->get(RedisFactory::class)->get('session');
            $existsKey = $redis->exists($sessionID);
            if ($existsKey !== 1) {
                return Str::random(40);
            }
        }
        $this->logger->notice('获取到 ' . microtime(true) . "\t" . 'Session => ' . $sessionID);
        return $sessionID;
    }

    public function getSessionName(): string
    {
        return 'HYPERF_SESSION_ID';
    }
}

发表评论

0/200
22 点赞
0 评论
收藏
为你推荐 换一批