하위 디렉토리에서 역방향 프록시를 사용하여 Symfony 5 실행
다음 엔드 포인트를 제공하는 리버스 프록시 뒤에서 Symfony 5 애플리케이션을 실행하고 싶습니다.
https://my.domain/service1/
프록시 구성은 기본적으로 다음과 같습니다.
ProxyPass /marketsy/ http://internal.service1/
역방향 프록시가 연결되는 서버에서 Symfony 애플리케이션을 제공하기 위해 다음 아파치 규칙을 사용합니다.
<VirtualHost *:80>
ServerName internal.service1
DocumentRoot /webroot/service1/public
<FilesMatch \.php$> SetHandler proxy:unix:/run/php/php7.2-fpm-ui.sock|fcgi://localhost SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
SetEnv HTTP_X_FORWARDED_PROTO "https"
</FilesMatch>
<Directory /webroot/service1/public>
AllowOverride None
Require all granted
FallbackResource /index.php
</Directory>
<Directory /webroot/service1/public/bundles>
FallbackResource disabled
</Directory>
</VirtualHost>
애플리케이션 자체는 요청 가능하지만 Symfony는 "service1"경로 접두어를 처리 할 수 없습니다.
예를 들어 다음에서 프로파일 러에 액세스하려고합니다. https://my.domain/_wdt/8e3926 대신에 https://my.domain/service1/_wdt/8e3926 루트 경로 옆에서 모든 라우팅이 작동하지 않습니다.
예 : 액세스하려고 할 때 https://my.domain/service1/my/page 나는 리디렉션 될 것이다 https://my.domain/my/page
이제 내 질문은 생성 URL 등을 사용할 때 "service1"경로 접두사에 대해 알도록 Symfony를 구성하는 방법입니다.
답변
적절한 방법 (예) :
창조하다 src/Controller/BarController.php
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class BarController
{
public function index()
{
return new Response('<p>Bar controler response</p>');
}
}
과 src/Controller/FooController.php
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class FooController
{
public function index()
{
return new Response('<p>Foo controler response</p>');
}
}
창조하다 config/routes/prefix-routes.yaml
index:
path: /
controller: App\Controller\DefaultController::index
bar:
path: /bar
controller: App\Controller\BarController::index
foo:
path: /foo
controller: App\Controller\FooController::index
라우팅 편집 config/routes.yaml
-내용을 삭제하고 다음을 입력하십시오.
prefixed:
resource: "routes/prefix-routes.yaml"
prefix: service1
이제 모든 컨트롤러를 URL에서 사용할 수 있습니다.
http://localhost/service1/ for DefaultController.php
http://localhost/service1/bar for BarController.php
http://localhost/service1/foo for FooController.php
프로파일 러가 service1
접두사로도 작동하도록 하려면 다음 과 같이 편집 config/routes/dev/web_profiler.yaml
하십시오.
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
prefix: service1/_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
prefix: service1/_profiler
이제 다음에서 사용할 수 있습니다.
http://localhost/service1/_wdt... for wdt
http://localhost/service1/_profiler for profiler
주석에 대한 접두사 추가 :
컨트롤러 만들기 src/Controller/AnnoController.php
:
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class AnnoController extends AbstractController
{
/**
* @Route("/anno", name="anno")
*/
public function index()
{
return new Response('<p>Anno controler response</p>');
}
}
편집 config/routes/annotations.yaml
및 추가 prefix: service1
:
controllers:
resource: ../../src/Controller/
type: annotation
prefix: service1
kernel:
resource: ../../src/Kernel.php
type: annotation
이제 주석을 통해 수행 된 경로에 접두사가 추가됩니다.
http://localhost/service1/anno for AnnoController.php
일부 참조 :
Symfony 라우팅 접두사
Symfony 라우팅 구성 키
접두사 추가 신속하고 더러운 해결하는 접두사를 추가하는 service1
라우팅의 모든 (권장하지 않음).
위와 같이 라우팅을 변경하는 대신 편집 src/Kernel.php
protected function configureRoutes
끝에 $routes->import
추가하여 모든 줄을 변경 ->prefix('service1')
하면 다음과 같이 보입니다.
protected function configureRoutes(RoutingConfigurator $routes): void
{
$routes->import('../config/{routes}/'.$this->environment.'/*.yaml')->prefix('service1');
$routes->import('../config/{routes}/*.yaml')->prefix('service1'); if (is_file(\dirname(__DIR__).'/config/routes.yaml')) { $routes->import('../config/{routes}.yaml')->prefix('service1');
} elseif (is_file($path = \dirname(__DIR__).'/config/routes.php')) { (require $path)($routes->withPath($path), $this);
}
}
이제 모든 컨트롤러를 URL에서 사용할 수 있습니다.
http://localhost/service1/ for DefaultController.php
http://localhost/service1/bar for BarController.php
http://localhost/service1/foo for FooController.php
뿐만 아니라 프로파일 러 :
http://localhost/service1/_wdt... for wdt
http://localhost/service1/_profiler for profiler
@Jimmix가 제공 한 솔루션 외에도 구독자를 작성하여 요청 경로에 접두사를 추가해야했습니다.
<?php namespace My\Bundle\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class AppPrefixSubscriber implements EventSubscriberInterface {
/** @var string */
private $appPrefix; public function __construct(?string $appPrefix) {
$this->appPrefix = $appPrefix;
}
/**
* Returns events to subscribe to
*
* @return array
*/
public static function getSubscribedEvents() {
return [
KernelEvents::REQUEST => [
['onKernelRequest', 3000]
]
];
}
/**
* Adds base url to request based on environment var
*
* @param RequestEvent $event */ public function onKernelRequest(RequestEvent $event) {
if (!$event->isMasterRequest()) { return; } if ($this->appPrefix) {
$request = $event->getRequest();
$newUri = $this->appPrefix .
$request->server->get('REQUEST_URI'); $event->getRequest()->server->set('REQUEST_URI', $newUri); $request->initialize(
$request->query->all(), $request->request->all(),
$request->attributes->all(), $request->cookies->all(),
$request->files->all(), $request->server->all(),
$request->getContent()
);
}
}
}