mercure

Mercure + Angular + Symfony >>> all on local machine


I'm local on Mac OS 10.14.6 using Angular 8, Symfony 4.3 and mercure 0.72 darwin. I'm quite new to symfony. I wanted to dispatch updates only to authorized clients on my local machine. So far it really is a big pain. I hope I can find some help or answers here.

Last error I get is

http: TLS handshake error from ip:55289: acme/autocert: unable to authorize "mydyndns-url.com"; challenge "http-01" failed with error: acme: authorization error for mydyndns-url.com: 400 urn:acme:error:connection: Fetching http://mydyndns-url.com/.well-known/acme-challenge/SomeHash: Error getting validation data; challenge "tls-alpn-01" failed with error: acme: authorization error for mydyndns-url.com: 400 urn:acme:error:connection: Connection refused

plus

http: TLS handshake error from ip:56803: acme/autocert: missing certificate

I have no remote server on which I could test anything. But I want to dispatch some updates to authorized clients. Is there no way for me to test this locally ? without any sll tls stuff ? So far if I understand correctly, to use authorization in clients (cookie or bearer) I must have encrypted mercure communication, for that I need a certificate, which I created with letsencrypt for my dyndns url, which I also just created for that, but then also I read that for the authorization with encrypt all must run on 443, but all is on one machine, so do I need to create subdomains for all my local test servers now ? (because there's a problem with my dyndns on certificate creation using sudo certbot certonly --standalone, it gives me Challenge failed for my sub domains, being then sub sub domains of the dyndns provider), then also why does he try to fetch a :80 server for the authorization with the .well-known path ?

But because I feel like I went down alices rabbithole and that it has no end, I don't know if it even makes anymore sense to try anything with mercure.

I just want to push a message on '/messages' to target '/user/patata' and then get that message in my angular client autherized using a cookie. Is it so hard to do that on a local development server ? Is there some complete doc for that use case?

Using this to launch mercure

sudo PUBLISHER_JWT_KEY='mercure_key' SUBSCRIBER_JWT_KEY='mercure_key' JWT_KEY='mercure_key' ACME_HOSTS='mydyndns-url.com' ADDR='mydyndns-url.com:443' CERT_FILE='/Users/me/Projects/fullchain.pem' KEY_FILE='/Users/me/Projects/privkey.pem' CORS_ALLOWED_ORIGINS='*' ALLOW_ANONYMOUS='1' debug='1' ./mercure

Of course theres also the symfony settings and code and angular code and so forth. But that would be too much to put everything in here. And mostly I'd like to know how to uncomplicate this, not to make you dizzy as well :D


Solution

  • OK, I managed to solve it (not perfect yet, but running, and it's for development only anyway).

    LoadModule proxy_module lib/httpd/modules/mod_proxy.so
    LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so
    
    <VirtualHost api.mydomain.dynu.org:443>
        DocumentRoot "/Users/me/Sites/api/public"
        ServerName api.mydomain.dynu.org
        SSLEngine on
        SSLCertificateFile "/Users/me/Projects/mydomain.dynu.org.crt"
        SSLCertificateKeyFile "/Users/me/Projects/mydomain.dynu.org.key"
        ErrorLog "/Users/me/Sites/api/error_log"
        CustomLog "/Users/me/Sites/api/access_log" common
    </VirtualHost>
    
    <VirtualHost client.mydomain.dynu.org:443>
        ServerName client.mydomain.dynu.org
        SSLEngine On
        SSLProxyEngine On
        ProxyRequests Off
        SSLCertificateFile "/Users/me/Projects/mydomain.dynu.org.crt"
        SSLCertificateKeyFile "/Users/me/Projects/mydomain.dynu.org.key"
    
        ProxyPass / http://client.mydomain.dynu.org:444/
        ProxyPassReverse / http://client.mydomain.dynu.org:444/
    </VirtualHost>
    
    <VirtualHost hub.mydomain.dynu.org:443>
        ServerName hub.mydomain.dynu.org
        SSLEngine On
        SSLProxyEngine On
        ProxyRequests Off
        SSLCertificateFile "/Users/me/Projects/mydomain.dynu.crt"
        SSLCertificateKeyFile "/Users/me/Projects/mydomain.dynu.key"
    
        ProxyPass / http://hub.mydomain.dynu.org:445/
        ProxyPassReverse / http://hub.mydomain.dynu.org:445/
    </VirtualHost>
    
    in '.env':
    MERCURE_PUBLISH_URL=https://hub.mydomain.dynu.org:443/hub
    CORS_ALLOW_ORIGIN=^https://client.mydomain.dynu.org$
    
    in 'nelmio_cors.yaml':
    nelmio_cors:
        defaults:
            ...
            origin_regex: true
        paths:
            ...
            '^/api/':
                allow_origin: ['^https://client.mydomain.dynu.org']
                allow_headers: ['Content-Type', 'Authorization']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
                max_age: 3600
            ...
    
            $username = $this->getUser()->getUsername(); // Retrieve the username of the current user
            $token = (new Builder())
                // set other appropriate JWT claims, such as an expiration date
                ->withClaim('mercure', ['subscribe' => ["/user/patata"], 'publish' => ['*']]) // could also include the security roles, or anything else
                ->sign(new Sha256(), 'mercure_key') // don't forget to set this parameter! Test value: aVerySecretKey
                ->getToken();
    
            $response = $this->json(['token' => sprintf('%s', $token)]);
    
    sudo PUBLISHER_JWT_KEY='mercure_key' SUBSCRIBER_JWT_KEY='mercure_key' \
    JWT_KEY='mercure_key' ADDR='hub.mydomain.dynu.org:445' \
    CORS_ALLOWED_ORIGINS='*' ALLOW_ANONYMOUS='1' DEBUG='1' ./mercure
    

    Follow all this above with care: - I'm quite new to symfony, always used flowframework before. - I never had to deal with setup or config of certificates before - And I never had to deal with any encryption setup, no JWT, no apache reverse proxy.

    History:
    I tried the mercure cookie token way before, buuut it didn't work and somewhere was written that you need encryption enabled for that, so that meant a certificates-way for me, but self generated didn't help and instead I read about using letsencrypt, so I went that way, till somewhere I read that letsencrypt only runs on 443 and so I read about proxies and went that way, not sure if it really had to be that way.
    Right now I would have new ideas without the certificates and stuff, which I'd try at the beginning, but everything runs now and I can develop again and that's all I wanted. And on that way I learned how to create letsencrypt certs, about reverse proxies and what acme is meant for :D.

    But if you have any suggestions, complaints, warnings, improvements, please let me know !!