0

我在这里关注了 Mercure 的 symfony 文档: https ://symfony.com/doc/current/mercure.html#programmatically-generating-the-jwt-used-to-publish

所以我创建了我的令牌提供程序,但是当我使用它时,我得到了 401。我错过了什么吗?

Symfony\Component\HttpClient\Exception\
ClientException
HTTP/1.1 401 Unauthorized returned for "http://mercure:3000/.well-known/mercure".

我转储集线器,我看到了一些不同:

当我使用秘密时,我得到了这个(一切都很好):

Symfony\Component\Mercure\Hub {#779 ▼
  -url: "http://mercure:3000/.well-known/mercure"
  -jwtProvider: Symfony\Component\Mercure\Jwt\FactoryTokenProvider {#741 ▶}
  -jwtFactory: Symfony\Component\Mercure\Jwt\LcobucciFactory {#782 ▶}
  -publicUrl: "http://localhost"
  -httpClient: Symfony\Component\HttpClient\TraceableHttpClient {#689 ▶}
}

并与提供者(得到 401):

Symfony\Component\Mercure\Hub {#782 ▼
  -url: "http://mercure:3000/.well-known/mercure"
  -jwtProvider: App\Mercure\MyTokenProvider {#781}
  -jwtFactory: null
  -publicUrl: "http://localhost"
  -httpClient: Symfony\Component\HttpClient\TraceableHttpClient {#697 ▶}
}

这里有一些代码:

配置/包/mercure.yaml

mercure:
    hubs:
        default:
            url: '%env(MERCURE_URL)%'
            public_url: '%env(MERCURE_PUBLIC_URL)%'
            jwt:
                provider: App\Mercure\MyTokenProvider
                # secret: '%env(MERCURE_JWT_SECRET)%'

src/Mercure/MyTokenProvider

<?php

namespace App\Mercure;

use Symfony\Component\Mercure\Jwt\TokenProviderInterface;

final class MyTokenProvider implements TokenProviderInterface
{
    public function getJwt(): string
    {
        $header = json_encode(['alg' => 'HS256','typ' => 'JWT']);

        $payload = json_encode(['mercure' => [ 'publish' => ['*'], 'subscribe' => ['*'] ]]);

        $base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));

        // Encode Payload to Base64Url String
        $base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));

        $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, 'secret', true);

        $base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));

        // Create JWT
        $jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;

        dump($jwt);

        return $jwt;
    }
}
4

0 回答 0