CORS и веб-расширения - PullRequest
       17

CORS и веб-расширения

0 голосов
/ 27 октября 2018

Я настроил сервер на http://localhost:8080, где http://example.com может выполнять запросы POST:

'use strict';

const express = require ('express');

const app = express();
const port = 8080;

// allowing CORS for example.com
app.use ('/', function (req, res, next){

    res.header ('Access-Control-Allow-Origin', 'http://example.com');

    if (req.method === 'OPTIONS'){

        res.header ('Access-Control-Allow-Methods', 'OPTIONS, POST');
        res.header ('Access-Control-Allow-Headers', 'Content-Type, Content-Length');
        res.status (200).send ();

    }else next();
});

// handling POST requests
app.use ('/', function (req, res){

    console.log ('a client did a POST request');
    res.status (200);
});

app.listen (port, () => console.log ('server started on port ' + port));

Работает нормально: я не могу выполнить запрос POST к http://localhost:8080 из http://localhost:8081 из-за той же политики происхождения.

Затем я написал веб-расширение для Firefox, которое попытается выполнить запрос POST к http://localhost:8080 из любого домена.

Вот его манифест:

{
    "manifest_version" : 2,
    "name" : "aBasicExtension",
    "version" : "0.0.0",

    "content_scripts" : [

        {
            "matches" : ["<all_urls>"],
            "js" : ["content-script.js"]
        }
    ],

    "permissions" : ["*://*.localhost/*"]
}

и content-script.js код:

(() => {

    'use strict';

    const xhr = new XMLHttpRequest();

    xhr.open ('POST', 'http://localhost:8080');
    xhr.setRequestHeader ('Content-Type', 'application/json; charset=utf-8');

    xhr.addEventListener ('readystatechange', () => {

        if (xhr.readyState === XMLHttpRequest.DONE){

            if (xhr.status === 200) console.log ('OK');
            else console.error ('an error has occured : ' + xhr.status);
        }
    });

    xhr.send (JSON.stringify ({dataName:'some data here'}));

})();

Что я не понимаю, так это то, что это работает. Расширение выполняет запрос к http://localhost:8080, и Firefox не блокирует его, потому что манифест это позволяет, однако сервер (http://locahost:8080) не дал свое разрешение .

1 Ответ

0 голосов
/ 27 октября 2018

Краткая версия: CORS - это протокол для управления поведением браузера, а не сервера.И ваше использование параметра addon permissions обходит CORS.

Если вы посмотрите на свой код CORS, вы увидите, что он ничего не делает для отклонения запросов;он просто устанавливает заголовки ответа.Эти заголовки сообщат браузеру, может ли клиент прочитать ответ, но ответ будет отправлен в любом случае.

Этот факт может быть скрыт определенными запросами, которые вызывают предварительную проверку CORS.В этом случае браузер сначала отправляет специальный запрос OPTIONS, а заголовки, прикрепленные к этому ответу, могут помешать браузеру отправлять реальный запрос.Это механизм обратной совместимости, который применяется не ко всем запросам.(См. этот ответ для более подробного объяснения.)

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

В версии аддона вы специально разрешили этот домен в настройке permissions. обходит CORS :

Дополнительные привилегии включают в себя: XMLHttpRequest и выборочный доступ к этим источникам без ограничений между источниками (даже для запросов, сделанных из скриптов содержимого).

Таким образом, в этом случае предварительная проверка не требуется, и запрос отправляется напрямую.

Если вы хотите отклонить запросы на сервере, поступающие из определенных доменов (или в целом защищать от CSRF)Будут другие настройки для этого.Что это такое, зависит от вашего веб-фреймворка.

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