Mercure – 401 with token provider

  mercure, php, symfony

I followed the symfony documentation for Mercure here:
https://symfony.com/doc/current/mercure.html#programmatically-generating-the-jwt-used-to-publish

So i create my token provider, but when i use it, i got a 401. Did i miss something ?

SymfonyComponentHttpClientException
ClientException
HTTP/1.1 401 Unauthorized returned for "http://mercure:3000/.well-known/mercure".

I dump the hub and i see some difference :

when i use the secret, i got this (everything is fine):

SymfonyComponentMercureHub {#779 ▼
  -url: "http://mercure:3000/.well-known/mercure"
  -jwtProvider: SymfonyComponentMercureJwtFactoryTokenProvider {#741 ▶}
  -jwtFactory: SymfonyComponentMercureJwtLcobucciFactory {#782 ▶}
  -publicUrl: "http://localhost"
  -httpClient: SymfonyComponentHttpClientTraceableHttpClient {#689 ▶}
}

and with the provider (got 401):

SymfonyComponentMercureHub {#782 ▼
  -url: "http://mercure:3000/.well-known/mercure"
  -jwtProvider: AppMercureMyTokenProvider {#781}
  -jwtFactory: null
  -publicUrl: "http://localhost"
  -httpClient: SymfonyComponentHttpClientTraceableHttpClient {#697 ▶}
}

Here some code:

config/package/mercure.yaml

mercure:
    hubs:
        default:
            url: '%env(MERCURE_URL)%'
            public_url: '%env(MERCURE_PUBLIC_URL)%'
            jwt:
                provider: AppMercureMyTokenProvider
                # secret: '%env(MERCURE_JWT_SECRET)%'

src/Mercure/MyTokenProvider

<?php

namespace AppMercure;

use SymfonyComponentMercureJwtTokenProviderInterface;

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;
    }
}

Source: Ask PHP

LEAVE A COMMENT