Mercure + Angular + Symfony >>> все на локальной машине
Я местный на 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 или носитель) я должен иметь зашифрованную связь mercure, для этого мне нужен сертификат, который я создал с помощью letsencrypt для моего URL-адреса dyndns, который я также только что создал для этого, но Затем я также прочитал, что для авторизации с шифрованием все должно работать на 443, но все находится на одном компьютере, поэтому мне нужно сейчас создавать поддомены для всех моих локальных тестовых серверов? (потому что есть проблема с моими dyndns при создании сертификата с использованиемsudo certbot certonly --standalone
, это дает мне ошибку Challenge для моих поддоменов, которые затем являются поддоменами провайдера dyndns), тогда также почему он пытается получить сервер:80 для авторизации с помощью хорошо известного пути?
Но поскольку я чувствую, что спустился в кроличью нору Алисы и что ей нет конца, я не знаю, имеет ли вообще смысл пробовать что-нибудь с меркуром.
Я просто хочу отправить сообщение в '/messages' для таргетинга '/user/patata', а затем получить это сообщение в моем угловом клиенте, авторизованном с помощью файла cookie. Неужели это так сложно сделать на локальном сервере разработки? Есть ли полный документ для этого варианта использования?
Используя это для запуска 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
1 ответ
Хорошо, мне удалось его решить (пока не идеально, но работает, и все равно только для разработки).
- Конечно, я создал свой JWT https://jwt.io/
- После настройки mercure для symfony https://symfony.com/doc/current/mercure.html
- В Symfony установлен
composer require symfony/mercure-bundle
- Я получил себе dyndns с подстановочным знаком с https://www.dynu.com/
- Я настроил свой роутер (
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)
привязан к моему публичному 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
- Я настраиваю свой apache с виртуальным хостом для своей Symfony
api.
и угловой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 был привязан к глобальному (это окно) переменная, потому что я просто не знаю, как лучше обрабатывать эти файлы, отличные от.ts. (может быть, кто-то может предложить реальное решение)
Токен, который я генерирую в Symfony
$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)]);
Я запускаю 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.
История:
я пробовал использовать токен cookie mercure раньше, но он не работал, и где-то было написано, что для этого нужно включить шифрование, так что это означало для меня способ сертификатов, но самогенерируемый не помог, и вместо этого я прочитал об использовании letsencrypt, поэтому я пошел по этому пути, пока где-то не прочитал, что letsencrypt работает только на 443, поэтому я читал о прокси и пошел по этому пути, не уверен, действительно ли это должно быть так.
Прямо сейчас у меня были бы новые идеи без сертификатов и прочего, что я бы попробовал вначале, но сейчас все работает, и я могу развиваться снова, и это все, что я хотел. Так я узнал, как создавать сертификаты letsencrypt, об обратных прокси и для чего предназначен acme:D.
Но если у вас есть предложения, жалобы, предупреждения, улучшения, дайте мне знать!!