另类用法 hyperf/session 实现 API token
前期准备
安装 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';
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: