Может ли приложение ReactJS с маршрутизатором быть размещено на S3 и запущено прокси-сервером nginx? - PullRequest
0 голосов
/ 18 марта 2019

Я могу ужасно крутить вещи, но ... Мне дали приложение ReactJS, которое должно быть разослано нескольким поддоменам, поэтому

   a.foo.bar
   b.foo.bar
   c.foo.bar
   ...

Каждый из них должен указывать надругой экземпляр приложения, но я не хочу запускать npm start для каждого - это было бы сумасшедшим количеством ресурсов сервера.

Так что я решил разместить их на S3.У меня есть корзина foo.bar, а затем под ней каталоги для a b c ... и я настроил эту корзину для обслуживания статических веб-сайтов.Пока все хорошо - если я пойду на https://s3.amazonaws.com/foo.bar/a/, я получу страницу индекса.Однако большинство вещей, как правило, ломаются оттуда, поскольку существуют не относительные ссылки на такие вещи, как /css/ или /somepath - они ломаются, потому что они недостаточно умны, чтобы понять, что их обслуживают из /foo.bar/a/,Кроме того, мы хотим, чтобы домен был добавлен в любом случае.

Так что теперь мне нужно сопоставить a.foo.bar -> https://s3.amazonaws.com/foo.bar/a/.Мы не размещаем наш домен в AWS, поэтому я не уверен, что это возможно с CloudFront или чем-то подобным.Открыт для решения в том же духе, но я не смог его найти.

Вместо этого я поднял простой прокси-сервер nginx.Я также добавил форсирование к https и некоторые другие вещи, пока у меня был прокси, что-то вроде:

server {
  listen       443;
  server_name  foo.bar;

  ssl                  on;
  ssl_certificate      /etc/pki/tls/certs/server.crt;
  ssl_certificate_key  /etc/pki/tls/certs/server.key;

  ssl_session_timeout  5m;

  ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers   on;

  # Redirect (*).foo.bar to (s3bucket)/(*)
  location / {
    index  index.html index.htm;

    set $legit "0";
    set $index "";

    # First off, we lose the index document functionality of S3 when we
    # proxy requests.  So we need to add that back on to our rewrites if
    # needed.  This is a little dangerous, probably should find a better
    # way if one exists.
    if ($uri ~* "\.foo\.bar$") {
      set $index "/index.html";
    }
    if ($uri ~* "\/$") {
      set $index "index.html";
    }

    # If we're making a request to foo.bar (not a sub-host),
    # make the request directly to "production"
    if ($host ~* "^foo\.bar") {
      set $legit "1";
      rewrite /(.*) /foo.bar/production/$1$index break;
    }

    # Otherwise, take the sub-host from the request and use that for the
    # redirect path
    if ($host ~* "^(.*?)\.foo\.bar") {
      set $legit "1";
      set $subhost $1;
      rewrite /(.*) /foo.bar/$subhost/$1$index break;
    }

    # Anything else, give them foo.bar
    if ($legit = "0") {
      return 302 https://foo.bar;
    }

    # Peform the actual proxy forward
    proxy_pass https://s3.amazonaws.com/;
    proxy_set_header Host s3.amazonaws.com;
    proxy_set_header Referer https://s3.amazonaws.com;

    proxy_set_header User-Agent $http_user_agent;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Accept-Encoding "";
    proxy_set_header Accept-Language $http_accept_language;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    sub_filter google.com example.com;
    sub_filter_once off;
  }
}

Это работает - я перехожу на a.foo.bar и получаю страницу индекса, которую яожидать, и щелкать вокруг работает.Однако часть приложения также выполняет вход в систему в стиле OAuth и ожидает, что браузер будет перенаправлен обратно на страницу по адресу / reentry? Token = foo ... Проблема в том, что путь существует только как маршрут в приложении React, иэто приложение не загружается статическим веб-сервером, таким как S3, поэтому вы просто получаете 404 (или 403, потому что у меня еще не определена или не отправлена ​​страница с ошибкой).

Итак .... Всечто за вопрос ...

Могу ли я обслуживать приложение ReactJS с тупого / статического сервера, такого как S3, и понимать ли оно обратные вызовы своих маршрутов?Имейте в виду, что директивы index / error в S3, по-видимому, отбрасываются при обращении к прокси, как я описал выше.

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

ОК, в моем первоначальном вопросе было много всего, но суть его действительно сводилась к следующему: как не пользователь UI, как заставить рабочий процесс OAuth работать с приложением React? URL обратного вызова в этом случае является маршрутом, который не существует, если вы выгружаете страницу index.html. Если вы идете непосредственно против S3, это решается путем направления всех ошибок в index.html, который перезагружает маршруты и обратный вызов работает.

Однако, когда выходит nginx, мы теряем эту маршрутизацию error-> index.html. К счастью, добавить ответ довольно просто:

  location / {
    proxy_intercept_errors on;
    error_page 400 403 404 500 =200 /index.html;

Вероятно, не нужны все эти коды состояния - для S3 важнее всего 403. Когда вы запрашиваете страницу, которая не существует, она будет обрабатывать ее так, как будто вы пытаетесь просмотреть корзину, и вернуть вам 403 запрещенных, а не 404 не найден или что-то в этом роде. Таким образом, в этом случае ответ от S3, который приводит к 403, будет перенаправлен в /index.html, который будет вызывать загруженные там маршруты и обратный вызов / callback? Token = ... будет работать.

0 голосов
/ 18 марта 2019

Вы можете использовать Route53, чтобы купить доменные имена, а затем направить их на свой сегмент S3, и вы можете сделать это с любым количеством доменов.

Строго говоря, вам не нужно трогать CloudFront, но эторекомендуется, так как это решение CDN, которое лучше для пользователя.

При развертывании приложений на S3 все, что вам нужно иметь в виду, это то, что код, который вы развертываете в нем, будет работать на вашем 100%браузер пользователя.Так что никаких серверных вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...