sessionless-1.x-dev/src/SessionlessOnlySign.php

src/SessionlessOnlySign.php
<?php

namespace Drupal\sessionless;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\sessionless\KeyStorage\KeyStorageInterface;
use Drupal\sessionless\Serialization\JsonSafeCompressingObjectAwareSerializationInterface;
use Drupal\sessionless\Utility\CacheTool;
use ParagonIE\Paseto\Builder;
use ParagonIE\Paseto\Exception\PasetoException;
use ParagonIE\Paseto\Keys\AsymmetricSecretKey;
use ParagonIE\Paseto\Parser;

/**
 * Only-signed-token service.
 *
 * Makes the token a bit smaller, but all payload data is public.
 */
final class SessionlessOnlySign implements SessionlessInterface {

  public function __construct(
    protected KeyStorageInterface $keyStorage,
    protected JsonSafeCompressingObjectAwareSerializationInterface $serializer,
    protected CacheBackendInterface $cache,
  ) {}

  public function encode(mixed $data): string {
    $signingSecretKey = $this->keyStorage->getSigningSecretKey();
    $cid = serialize([__METHOD__, $signingSecretKey, $data]);
    return CacheTool::getOrCompute($this->cache, $cid,
      fn() => $this->doEncode($signingSecretKey, $data));
  }

  private function doEncode(AsymmetricSecretKey $signingSecretKey, mixed $data): string {
    $token = Builder::getPublic($signingSecretKey)
      ->set('data', $this->serializer->encode($data));
    return $token->toString();
  }

  public function decode(string $token): mixed {
    $signingSecretKey = $this->keyStorage->getSigningSecretKey();
    $cid = serialize([__METHOD__, $signingSecretKey, $token]);
    return CacheTool::getOrCompute($this->cache, $cid,
      fn() => $this->doDecode($signingSecretKey, $token));
  }

  private function doDecode(AsymmetricSecretKey $signingSecretKey, string $token): mixed {
    $parser = Parser::getPublic($signingSecretKey->getPublicKey());
    try {
      $jsonToken = $parser->parse($token);
      $serialized = $jsonToken->get('data');
      // Unserializing is no attack vector, as at this point the cryptographic
      // data signature is validated, and whatever classes are unserialized, it
      // is us, that put it in there.
      $data = $this->serializer->decode($serialized);
    }
    catch (PasetoException) {
      $data = NULL;
    }
    return $data;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc