Safari не отправляет cook ie на Express при запросе изображения через p5 loadImage () - PullRequest
1 голос
/ 01 мая 2020

Фон

Я настроил приложение Express. js на прокси-сервере , чтобы пользователи могли войти в систему, прежде чем их перенаправят в веб-приложение. Это приложение не может обслуживать некоторые изображения в Safari (macOS / iOS), потому что Safari не отправляет повару ie обратно с запросами изображений , которые исходят из метода loadImage() в моем p5 . js код. Это не происходит на Chrome (macOS).

Когда я загружаю страницу, браузер нормально запрашивает ресурсы. Но запросы, исходящие из моего приложения, возвращают другой сеанс, который не вошел в систему, и обрабатываются Express:

// Request for the main page by the browser
Session {
  cookie:
   { path: '/',
     _expires: 2020-05-04T16:26:00.291Z,
     originalMaxAge: 259199998,
     httpOnly: true,
     secure: true },
  loggedin: true }

// Request for image assets by a script in my application
Session {
  cookie:
   { path: '/',
     _expires: 2020-05-04T16:26:00.618Z,
     originalMaxAge: 259200000,
     httpOnly: true,
     secure: true } }

HTTP-запросов от Safari

GET https://mydomain/app/img/svg/Water.svg HTTP/1.1
Host: mydomain
Origin: https://mydomain
Connection: keep-alive
If-None-Match: W/"5e6-171c689d240"
Accept: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
If-Modified-Since: Wed, 29 Apr 2020 15:24:13 GMT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
Referer: https://mydomain/app/
Accept-Language: en-us
Accept-Encoding: gzip, deflate, br

HTTP/1.1 302 Found
Date: Fri, 01 May 2020 06:50:07 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.3.17
X-Powered-By: Express
Location: /
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 23
Access-Control-Allow-Origin: *
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

Found. Redirecting to /

Express app

Приложение настроено за HTTPS-прокси, поэтому я установил для объекта Express Session доверенный прокси-сервер и установил безопасность на auto (установка в false не устраняет проблему):

app.set('trust proxy', 1)
app.use(session({
    secret: 'my-secret',
    resave: true,
    saveUninitialized: true,
    cookie: {
        secure: 'auto',
        maxAge: 259200000
    }
}));

Когда пользователь входит в систему, он отправляется на /auth для проверки базы данных

app.post('/auth', function (request, response) {
    var user = request.body.user;
    var password = request.body.password;

    if (user && password) {
        connection.query('SELECT * FROM accounts WHERE user = ? AND password = ?', [user, password], function (error, results, fields) {
            if (results.length > 0) {

                request.session.loggedin = true;

                // If the user logs in successfully, then register the subdirectory
                app.use("/app", express.static(__dirname + '/private/'));

                // Then redirect
                response.redirect('/app');
            } else {
                response.send('Incorrect password!');
            }
            response.end();

            if (error) {
                console.log(error);
            }
        });
    } else {
        response.send('Please enter Username and Password!');
        response.end();
    }
});

Они перенаправляются на /app при входе в систему:

app.all('/app/*', function (request, response, next) {

    if (request.session.loggedin) {    
        next(); // allow the next route to run
    } else {
        // The request for images from my p5 script fails and these request redirect to "/"
        response.redirect("/");
    }
})

Вопрос

Что можно сделать, чтобы Safari передал сессионному повару ie с его запросом, чтобы Express вернул правильный ресурс?


Редактировать

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

loadParticleImage() {

    return new Promise((resolve, reject) => {

        loadImage(this.imageUrl, (result) => {

            // Resolves the Promise with the result
            resolve(result);

        }, (reason) => {

            console.log(reason);
        });
    })
}

Редактировать # 2

Включая заголовки для успешного запроса непосредственно по URL-адресу актива изображения:

GET https://mydomain/app/img/svg/Water.svg HTTP/1.1
Host: mydomain
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cookie: connect.sid=s%3A2frOCv41gcVRf1J4t5LlTcWkdZTdc8NT.8pD5eEHo6JBCHcpgqOgszKraD7AakvPsMK7w2bIHlr4
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
Accept-Language: en-us
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Ответы [ 2 ]

2 голосов
/ 01 мая 2020

Вызов fetch() в исходном коде для этой функции loadImage() не устанавливает параметр credentials , который определяет, включены ли файлы cookie в запрос или нет, поэтому они не отправляются с запросом.

Вам действительно нужна аутентификация перед передачей изображения? Если нет, вы можете изменить порядок обслуживания изображений на сервере, чтобы они могли обслуживаться без аутентификации, используя express.static(), указывающий на каталог, содержащий только ресурсы, которые можно обслуживать без аутентификации. Если они действительно должны быть аутентифицированы, вам, возможно, придется пропатчить код loadImage(), чтобы использовать опцию credentials: include, или загрузить изображения другим способом.

2 голосов
/ 01 мая 2020

Я предлагаю использовать express stati c middleware для обслуживания stati c файлов. При этом вам не понадобится сеанс для получения изображений, js, css и др. c. Кроме того, это ускоряет ваше приложение. Вам нужно поместить

app.use(express.static( ... )) 

перед оператором app.use(session( ... )), если вам нужна дополнительная производительность, потому что если вы это сделаете, express не будет присутствовать при создании сеанса для stati c файлов.

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