Mercure + Angular + Symfony >>> 全部在本地机器上

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

我在 Mac OS 10.14.6 本地使用 Angular 8、Symfony 4.3 和 mercure 0.72 darwin。我对symfony很陌生。 我只想将更新发送给本地机器上的授权客户端。到目前为止,这确实是一个很大的痛苦。我希望我能在这里找到一些帮助或答案。

我得到的最后一个错误是

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

加上

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

我没有可以测试任何内容的远程服务器。 但我想向授权客户发送一些更新。我没有办法在本地测试吗?没有任何 sll tls 的东西? 到目前为止,如果我理解正确,要在客户端(cookie 或 bearer)中使用授权,我必须加密 mercure 通信,为此我需要一个证书,我用 letsencrypt 为我的 dyndns url 创建了这个证书,我也是刚刚创建的为此,但后来我也读到关于加密的授权必须在 443 上 运行,但所有都在一台机器上,所以我现在需要为我所有的本地测试服务器创建子域吗? (因为我的 dyndns 在使用 sudo certbot certonly --standalone 创建证书时出现问题,它给我的子域挑战失败,然后是 dyndns 提供商的子子域),那么他为什么要尝试获取 :80具有 .well-known 路径的授权服务器 ?

但是因为我觉得我已经掉进了 alices rabbithole 并且没有尽头,所以我不知道用 mercure 尝试任何事情是否还有意义。

我只想在“/messages”上将消息推送到目标“/user/patata”,然后在使用 cookie 授权的 angular 客户端中获取该消息。在本地开发服务器上这样做有那么难吗?该用例是否有完整的文档?

使用它启动 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

当然还有symfony设置和代码以及angular代码等等。但是,将所有内容都放在这里太过分了。主要是我想知道如何简化这个,而不是让你头晕 :D

好的,我设法解决了它(还不完美,但是运行宁,而且它只是为了开发)。

  • 我当然生成了我的 JWT https://jwt.io/#debugger-io
  • 遵循 symfony 的 mercure 设置 https://symfony.com/doc/current/mercure.html#running-a-mercure-hub
  • 已安装 Symfony composer require symfony/mercure-bundle
  • 我从 https://www.dynu.com/
  • 获得了一个带通配符的 dyndns
  • 我将路由器 (fritzbox) 配置为 forward port 80 and 443 http。 (暂时,仅用于 certbot 证书创建!!!)
  • 我打电话给sudo ifconfig lo0 alias [public IP] up
  • 我将我的 dyndns 域的三个子域添加到我的 /etc/hosts 文件 (client.mydomain.dynu.org,api.mydomain.dynu.org,hub.mydomain.dynu.org) 绑定到我的 public IP。
  • 我将 letsencrypt certbot 与 sudo certbot certonly --standalone 一起使用,并为 4 个域创建了一个证书 (client.mydomain.dynu.org,api.mydomain.dynu.org,hub.mydomain.dynu.org,mydomain.dynu.org)
  • 然后我更改了 /etc/hosts 文件并将所有 4 个域绑定到 127.0.0.1
  • 我配置了我的 apache 来加载代理插件
LoadModule proxy_module lib/httpd/modules/mod_proxy.so
LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so
  • 我为我的 symfony api. 和 angular client. 子域设置了一个虚拟主机(我不使用 symfony server:start
<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>
  • 在 symfony 中我设置:
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
        ...
  • 在 angular 中,我使用 EventSourcePolyfill 就像这里描述的那样 https://www.npmjs.com/package/event-source-polyfill 来传输 Bearer 令牌,但需要更改源文件以将 EventSourcePolyfill 绑定到全局(它是window) 变量,因为直到现在我还不知道如何更好地处理这些非 .ts 文件。 (也许有人可以提供真正的解决方案)

  • 我在symfony中生成的token

        $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)]);
  • I 运行 angular 在端口 444 sudo ng serve --host client.mydomain.dynu.org --port 444 上,apache 反向代理将 443 上的所有请求转发到那个

  • 我使用

  • 启动 mercure
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

请仔细遵循以上所有内容: - 我是 symfony 的新手,之前一直使用 flowframework。 - 我以前从未需要处理证书的设置或配置 - 而且我从来不需要处理任何加密设置,没有 JWT,没有 apache 反向代理。

历史:
我之前尝试过 mercure cookie 令牌方式,但是它没有用,并且在某处写到你需要为此启用加密,所以这对我来说意味着证书方式,但自我生成并没有帮助,而是我阅读了关于使用letsencrypt,所以我就这么走了,直到我在某个地方读到 letsencrypt only 运行s on 443 所以我读了关于代理的信息然后就那样走了,不确定是否真的必须那样。
现在我会在没有证书和东西的情况下有新的想法,一开始我会尝试这些,但是现在一切 运行s 我可以再次开发,这就是我想要的。通过这种方式,我学会了如何创建 letsencrypt 证书、关于反向代理以及 acme 的用途 :D.

但如果您有任何建议、投诉、警告、改进,请告诉我!!