Решение междоменной проблемы с интерфейсом (на основе node и nginx)

внешний интерфейс

1. Что такое междоменный домен

  Кросс-доменный относится к процессу отправки запроса на адрес назначения, который не является исходным (любой из протоколов, доменных имен, портов отличается), поэтому проблема связана с ограничениями политики одного и того же источника браузера. Кажется, что политика одного и того же происхождения влияет на плавность нашего развития.На самом деле это не так.Одна из необходимости политики того же происхождения, чтобы изолировать атаки.

Политика того же источника ограничивает взаимодействие документов или сценариев, загруженных из одного источника, с ресурсами из другого источника. Это важный механизм безопасности для изоляции потенциально вредоносных файлов.

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

CSRF

  CSRF, также известная как подделка межсайтовых запросов, относится к нелегальным веб-сайтам, перехватывающим пользователейcookieАтаки, которые осуществляют незаконные операции на зарегистрированном веб-сайте, основаны на практичности использования файлов cookie для сохранения логина и информации о пользователе на веб-сайте.Далее давайте поговорим об обычном процессе запроса входа на веб-сайт. Процесс запроса выглядит следующим образом:

  1. Мы заходим на веб-сайт и отправляем запрос на вход в бэкэнд
  2. Серверная часть принимает запрос на вход и определяет, является ли информация для входа точной.
  3. Убедившись, что информация верна, серверная часть отправит ответ браузеру и добавит поле set-cookie в заголовок ответа.
  4. Браузер принимает ответ и возвращает его пользователю, сохраняя куки в заголовке.
  5. После того, как пользователь закроет текущее окно веб-сайта и снова откроет его, браузер автоматически добавит файл cookie в заголовок запроса, чтобы обеспечить отсутствие входа в систему.

Мы представляем себе такой сценарий

  1. Сяо А вошел на веб-сайт онлайн-банкинга, и браузер, в котором находится Сяо А, записывает файл cookie, возвращенный онлайн-банкингом.
  2. В это время он получил ссылку на QQ, что такое казино Макао, красивый дилер, веб-сайт b, который отправляет деньги онлайн.
  3. После того, как он нажмет на ссылку, веб-сайт b может отправить запрос в систему онлайн-банкинга с файлом cookie, установленным браузером.

Результаты очевидны, начиная от утечки информации и заканчивая финансовыми потерями, а обычное время хранения файлов cookie — до закрытия браузера, а не веб-сайта, поэтому многие пользователи считают безопасным открывать веб-сайт Макао после закрытия веб-сайта. сайт вверх эмммм.

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

2. Решения междоменных проблем

1.jsonp

Одним из первых решений является jsonp, который реализуется путем передачи данных через теги скрипта.Поскольку запросы скриптов не будут запрещены политикой одного и того же источника, междоменные данные запрашиваются через теги скрипта, а данные реализуются в func соответствующий cb сценария. Приобретение возможно. Конечно, этот метод требует сотрудничества с серверной частью. Серверная часть возвращает соответствующие данные формата jsonp, когда внешний интерфейс делает соответствующий запрос. Дело в php выглядит следующим образом:

<?php
header('Content-type: application/json');
//获取回调函数名
$jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
//json数据
$json_data = '["customername1","customername2"]';
//输出jsonp格式的数据
echo $jsoncallback . "(" . $json_data . ")";
?>

  Клиент использует следующее:

 <script type="text/javascript">
		function callbackFunction(result, methodName)
        {
            ///result 指向对应数据
        }
</script>
<script type="text/javascript" src="http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script>

2.CORS

  Следующее, о чем мы говорим, это наш главный геройCORS, так что же такое CORS?

Совместное использование ресурсов между источниками (CORS) — это механизм, который использует дополнительные заголовки HTTP, чтобы сообщить браузерам, что веб-приложениям, работающим в одном источнике (домене), разрешен доступ к указанным ресурсам с серверов в разных источниках. Когда ресурс запрашивает ресурс из домена, протокола или порта, отличного от сервера, на котором находится сам ресурс, ресурс инициирует междоменный HTTP-запрос.

  CORS далее делится напростой запросипредварительный запрос

простой запрос

Простые запросы, определенные mdn, — это запросы, которые не запускают предварительную проверку cors.

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

  1. Настройка не вызывает предварительный результатMethods : GET,HEAD,POST. Все знакомы с GET и POST, поэтому я не буду повторять их здесь. Давайте объясним запрос HEAD. HEAD — это метод запроса, который только отправляет запрос и не получает ответ. Он редко используется ежедневно.

  2. Простые запросы могут устанавливать только следующие заголовки следующим образом.Accept,Accept-Language,Content-Language,Content-Type

  3. Content-TypeЕдинственные допустимые значения для заголовка: приложение/x-www-форма-urlencoded, multipart/form-data, текст/обычный

Схема адаптации back-end: добавить в заголовок ответовAccess-Control-Allow-Origin

'Access-Control-Allow-Origin':'xxx'

  Access-Control-Allow-Origin представляет источник, которому разрешено отправлять запросы. Параметр может быть фиксированным IP-адресом из белого списка или подстановочным знаком, а подстановочный знак "*" может использоваться для принятия всех запросов. Однако есть особый случай, когда подстановочные знаки использовать нельзя, т. е. заголовок внешнего запроса содержитwithCredentials, withCredentials:true — это конфигурация заголовков, которая должна быть добавлена ​​к междоменным запросам, которые хотят переносить файлы cookie.

предварительный запрос

  предварительный запросЭто необходимо для установки соответствующего содержимого, которое необходимо предварительно проверить при междоменном взаимодействии. В результате запрос параметров будет добавлен перед обычным междоменным запросом, чтобы проверить, находится ли изменение заголовков внешнего интерфейса в пределах допустимого. допустимый диапазон задней части. Основные ситуации, которые запускают предварительные запросы при междоменной разработке, следующие:

  1. Настройки первых методовPUT,DELETE,CONNECT,OPTIONS,TRACEприведет к предварительному запросу
  2. уже настроенAccept,Accept-Language,Content-Language,Content-TypeКонфигурация любого из заголовков, кроме этих, таких как общий токен:авторизация, механизм кэширования cache-contorl
  3. Content-TypeУстановлено значение, которое не разрешено для простых запросов, например часто используемое приложение/json

Итак, что нам нужно сделать с предварительным запросом?

Запросы предварительной проверки требуют, чтобы серверная часть устанавливала больше заголовков ответа, которые обычно используются следующим образом:

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
  • Access-Control-Allow-MethodsПредставляет приемлемые методы
  • Access-Control-Allow-HeadersПредставляет допустимые модификации заголовка
  • Access-Control-Max-AgeПредставляет остаточное время предварительной проверки и представляет время, которое может быть освобождено от предварительной проверки после предварительной проверки.

Кроме того, серверная часть также должна установить суждение о запросе опций, суждение, которое я добавил в промежуточное ПО узла, выглядит следующим образом:

if (req.method == 'OPTIONS') {
    res.send(200);
  } else {
    next();
  }

   Более подробное содержание cors можно увидеть:developer.Mozilla.org/en-US/docs/…

Несколько способов реализации CORS

  1. локальный прокси
  2. промежуточное ПО nodejs
  3. nginx-прокси

локальный прокси

   реализуется в dva добавлением следующего кода в .webpackrc

 "proxy": {
    "/api": {
      "target": "http://127.0.0.1:8988/",
      "changeOrigin": true,
      "pathRewrite": { "^/api" : "" }
    }
  }

  /api представляет собой путь к прокси-серверу, target представляет собой адрес прокси-сервера, changeOrigin представляет собой изменение исходного адреса на целевой, pathRewrite представляет собой перезапись пути, а другие шаблоны могут напрямую загружать файл конфигурации веб-пакета.

междоменное промежуточное ПО nodejs

   Конкретный процесс реализации, который я используюexpress+http-proxy-middleware

  1. Создавайте экспресс-трафареты с помощью экспресс-скаффолдинга
npm install express-generator -g
express --view=pug myapp
  1. Настроить перехват глобального маршрута
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
if (req.method == 'OPTIONS') {
  res.send(200);
} else {
  next();
}
})
  1. Затем установите соответствующую логику прокси
var options = {
  target: 'https://xxxx.xxx.xxx/abc/req',
  changeOrigin: true,
  pathRewrite: (path,req)=>{
    return path.replace('/api','/')
  }
}
app.use('/api', proxy(options));
  1. Введите bin/www, чтобы установить соответствующий порт, или установите значение запуска порта в process.env.PORT.
var port = normalizePort(process.env.PORT || '7002');
  1. начать строительные леса
DEBUG=myapp:* npm start

После запуска агента вы можете напрямую запросить промежуточное ПО в соответствующем проекте для достижения междоменного

Междоменный прокси Nginx

  NginxЭто асинхронный веб-сервер для обратного прокси-сервера, используемый иностранными богами. Помимо использования для обратного проксирования, его также можно использовать для балансировки нагрузки и кэширования HTTP. Далее мы представим метод установки Сначала установите Nginx для установки Homebrew, Однако на моем Mac нет Homebrew, поэтому мне нужно сначала установить этот менеджер пакетов с Ruby.

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

   Проверьте, успешно ли установлен brew. После успешной установки Nginx можно установить без проблем.

brew -v
brew install nginx
nginx -v

  Общие команды Nginx:

#查看版本,以及配置文件地址
nginx -V
#查看版本 
nginx -v
#指定配置文件
nginx -c filename
#帮助
nginx -h
#重新加载配置|重启|停止|退出 nginx
nginx -s reload|reopen|stop|quit
#打开 nginx
sudo nginx
#测试配置是否有语法错误
sudo nginx -t

   Затем нужно войти в конфигурационный файл Nginx

sudo vim /usr/local/etc/nginx/nginx.conf

  ps: Общие элементы конфигурации nginx-http следующие:

http {
    #导入类型配置文件
    include       mime.types;
    #设定默认类型为二进制流
    default_type  application/octet-stream;
    #启用sendfile()函数
    sendfile        on;
    #客户端与服务器连接的超时时间为65秒,超过65秒,服务器关闭连接
    keepalive_timeout  65;
    #是否开启gzip,默认关闭
    #gzip  on;
    #一个server块
    server {
        #服务器监听的端口为80
        listen       80;
        #服务器名称为localhost,我们可以通过localhost来访问这个server块的服务
        server_name  localhost;
        #location块,它存放在server块当中,location会尝试根据用户请求中的URI来匹配上面的/uri表达式,如果可以匹配,就选择location {}块中的配置来处理用户请求。
        location / {
            #以root方式设置资源路径,它与alias的不同请见下面的 http模块中文件路径定义
            root   html;
            #默认访问的页面,从左依次找到右,直到找到这个文件,然后返回结束请求
            index  index.html index.htm;
            #设置错误页面,对应的错误码是404,错误页面是/Users/user/Sites/404.html
            error_page 404  /404.html;
        }
    }
    include servers/*;
}

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

server {
        listen       80;
	server_name  localhost;
	location / {
            root   /Users/abc/dist/;
            index  index.html index.htm;
        }

        location /api/ {
                proxy_pass  https://xxx.xxx.xxx/req/;
        }
}

Содержимое после   location попытается сопоставить приведенное выше выражение /uri в соответствии с URI в запросе пользователя. Если оно может быть сопоставлено, для обработки запроса пользователя будет выбрана конфигурация в блоке location {}.

   Первое местоположение в этом проекте используется для указания на местоположение статического ресурса root: каталог, индекс: входной файл, а второе местоположение используется для междоменного указания API.

   Если вы хотите реализовать прокси для разных портов, вы можете настроить несколько серверов Слушайте тот же порт, оценивайте источник запроса по имени сервера и устанавливайте место назначения прокси-сервера в соответствии с местоположением.

  См. здесь, если вы не столкнулись с проблемами разрешения, то поздравляем, если вы это сделаете, посмотрите советы 3

  nginx шагает по яме:

  1. nginx нужно перезапускать после каждой модификации conf, а также обязательно sudo
  2. nginx -s reload иногда теряет PID по необъяснимым причинам.Многие решения в Интернете рекомендуют nginx -c для решения этой проблемы.На самом деле служба nginx все еще работает при перезагрузке. "адрес уже используется" На данный момент необходимо убить соответствующий процесс. . . .
ps -ef | grep nginx 查询进程号
sudo kill -QUIT 主进程号 杀掉主进程号
sudo nginx 即可
  1. Проблема разрешений NGINX Проблема разрешений является самым жалким, но вы ничего не можете сказать, потому что это разумно и разумно, его основной метод отображения состоит в том, что ваш сайт статического ресурса всегда будет отображаться как 403, который обычно возникает, когда Dist Directory отделяется от каталог NGINX., иногда появится при модификации -T после конфета Разрешения должны быть установленыsudo chown -R 'username' /usr/xxx/xxx/run/nginx.pidЯма в том, что это может решить проблему отсутствия разрешений только тогда, когда вы -t 403 также необходимо добавить конфигурацию в nginx.confuser your_username staff;Установка имени пользователя nginx может решить проблему разрешений 403.

Расширение темы nginx также можно использовать для достижения множественного входа

server {
        listen       80;
	server_name  www.aaa.com;
        location /api/ {
                proxy_pass  http://localhost:7001;
        }
}
server {
        listen       80;
	server_name  www.bbb.com;
        location /api/ {
                proxy_pass  http://localhost:7002;
        }
}

  nginx также имеет функцию реализации балансировки нагрузки, поэтому я не буду здесь ее подробно раскрывать

3. Сравнение решений

Сравнивая jsonp и cors, преимущества и недостатки этих двух заключаются в следующем.

  1. JSON поддерживает только запросы на получение и не может поддерживать сложные запросы.
  2. Когда есть ошибка в jsonp, ее трудно идентифицировать и обрабатывать ошибки, а cors может нормально фиксировать ошибки.
  3. Совместимость jsonp относительно высока, и cors нужно найти соответствующую альтернативу в старой версии ie.

Совместимость cors следующая:

undefined
ПК и мобильные браузеры отлично поддерживаются, но проблема в том, что вам нужно найти решение для понижения версии в более низкой версии ie.

   Что касается преимуществ и недостатков трех схем прокси CORS, то основные преимущества и недостатки заключаются в следующем:

  1. Настроить прокси webpack-dev-server проще всего, но обычно его можно использовать только в локальной среде, а онлайн-среду обычно нельзя проксировать напрямую.
  2. Написание агента узла является более удобным и гибким и не требует слишком больших затрат на обучение. Внешний интерфейс понимает определенные внутренние знания, а затем записывает захват исключений, чтобы начать работу. Вы также можете выполнять некоторые бизнес-обработки, такие как перехват полученных Запросы.
  3. Nginx — самое гибкое решение для реализации прокси, и его производительность намного выше, чем у узла.Сам Nginx славится меньшим потреблением ресурсов, высокой степенью параллелизма и эффективной обработкой статических ресурсов и обратных прокси.Nginx также более стабилен. в то же время уровень использования памяти ЦП низкий, процесс асинхронной обработки может лучше выдерживать нагрузку, и один и тот же процесс может столкнуться с тысячами подключений.Объяснение производительности nginx можно прочитать следующим образом:Вуху.. Mommycode.com/info-detail…

Подводя итог, можно сказать, что и нода, и nginx могут реализовать функцию прокси, обе являются асинхронными и неблокирующими моделями, которые вполне могут поддерживать высокочастотные запросы с фронтенда, нода может реализовать перехват и вторичное управление запросами, в то время как nginx находится в Лучше реализовать прокси-сервер статических ресурсов и обратный прокси-сервер, и nginx также имеет высокую стабильность и высокую поддержку параллелизма.В определенной степени они могут быть объединены.Перехват узла + обратная генерация nginx также является идеей

мышление

На самом деле, nginx не считается внешним информационным контентом, узел — это промежуточное программное обеспечение внешнего прокси, которое может быть легко подключено, но собственное превосходство nginx и тесная интеграция с внешними запросами могут фактически использоваться как расширение внешнего интерфейса. конечная система знаний.

Использованная литература:

  1. Та же политика происхожденияdeveloper.Mozilla.org/this-cn/docs/…

  2. cors developer.Mozilla.org/en-US/docs/…

  3. экспресс китайский сайтwww.expressjs.com.cn/

  4. официальный сайт нгинксnginx.org/en/docs/

  5. объяснение производительности nginxВуху.. Mommycode.com/info-detail…