2015-06-15 2 views
1

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

app.all('/*', function (req, res, next) { 
    // CORS headers 
    res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain 
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); 
    // Set custom headers for CORS 
    res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key'); 
    if (req.method == 'OPTIONS') { 
     res.status(200).end(); 
    } else { 
     next(); 
    } 
}); 

В настоящее время на многих компьютерах и браузерах это работает отлично (в том числе мои собственные), однако кто-то кто не сидит в моем кабинете получает следующее сообщение об ошибке:

enter image description here

Ладно то будет Abit трудно читать так здесь две ошибки:

  1. Не удалось загрузить ресурс: Origin http://angular.mydomain.com не допускается Access-Control-Allow-Origin
  2. XMLHttpRequest не может загрузить http://angular.mydomain.com:8080/login. Происхождение http://angular.mydomain.com не разрешено Access-Control-Allow_origin.

Может ли кто-нибудь сказать мне, что происходит здесь?

Headers

enter image description here

Войти маршрут:

router.route('/login') 
.post(function (req, res) { 
    var user = User.build(); 

    var username = req.body.username || ''; 
    var password = req.body.password || ''; 

    if (username == '' || password == '') { 
     res.status(401); 
     res.json({ 
      "status": 401, 
      "message": "Invalid credentials" 
     }); 
     return; 
    } 
    var salt = bcrypt.genSaltSync(10); 
    var hash = bcrypt.hashSync(password, salt); 


    user.retrieveByNamePassword(username, function (users) { 
     var i = 0; 
     if (bcrypt.compareSync(password, users.password)) { 
      var log = User_Login.build() 
      log.findLastLogin(users.id, function (result) { 
       users.last_login = result; 
       if (users.user_type_id > 3) { 
        res.json(genToken(users, null)); 
       } 
       else { 
        var div = Division.build(); 
        selected_user = users; 
        var root = [selected_user.division_id]; 
        div.retrieveByDivisionId(selected_user.division_id, function (division) { 
         var result = []; 
         var root = [division]; 
         (function loop() { 
          var element = root[0]; 
          var divisions = Division.build(); 
          divisions.retrieveByParentId(element.id, function (divisions) { 
           if (divisions) { 
            divisions.forEach(function (division) { 
             root.push(division); 
            }); 
            result.push(element.id); 
            root.splice(0, 1); 
            if (root.length > 0) { 
             loop() 
            } 
            else if (root.length == 0) { 
             res.json(genToken(users, result)); 
            } 
           } else { 
            res.send(401, "No division found"); 
           } 
          }); 
         }()); 
        }) 
       } 
      }, function (error) { 
       var i = 0; 
      }); 

     } else { 
      // If authentication fails, we send a 401 back 
      res.status(401); 
      res.json({ 
       "status": 401, 
       "message": "Invalid credentials" 
      }); 
      return; 
     } 
    }, function (error) { 
     res.status(401); 
     res.json({ 
      "status": 401, 
      "message": "Invalid credentials" 
     }); 
     return; 
    }); 
}); 
+0

Может ли этот человек («тот, кто не сидит у меня в офисе») подтвердить, какие заголовки CORS они получают (или не получают) в Сетевом регистраторе браузера? Аналогично, можете ли вы подтвердить, что сервер устанавливает эти заголовки? В частности, я хотел бы исключить возможность прокси-сервера где-нибудь, снимающего заголовки. – apsillers

+0

@ перехватчики на минуту заставляют его отправить мне скриншот его вкладки в сети –

+0

@apsillers добавлены заголовки –

ответ

0

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

+0

На сетевой вкладке нет ответа 400, 404 или 500 –

0

Настоящий случай экспресс пытается обрабатывать запрос OPTIONS. Я рекомендую исправление в последнем абзаце, но прочитайте, если вы хотите более подробно понять, почему это происходит.

Почему существует запрос OPTIONS? Это то, что называется «предполетным» (read about it here). По существу, если запрос является кросс-происхождение и выглядит «опасные» («безопасные» запросы GET/HEAD/POST без каких-либо специальных заголовков и один из application/x-www-form-urlencoded/multipart/form-data/text/plain как Content-Type), браузер сначала посылает OPTIONS запроса убедитесь, что запрос на перекрестный поиск будет разрешен. Если правильные заголовки установлены, он отправит фактический запрос.

Вы пытаетесь установить правильные заголовки в обработчике app.all, но они не присутствуют в ответе.

Во-первых, давайте посмотрим, как экспресс обрабатывает запрос. Сначала он запускает все промежуточное программное обеспечение, прикрепленное к app (в том порядке, в котором он был прикреплен). «Middleware» - это все, что связано с app.use. Затем он проходит через каждый маршрут в том порядке, в котором они были прикреплены. Маршруты - это все, что связано с app.all, app.get и т. Д. Если какой-либо из этих шагов не вызвал next (как правило, поскольку они отправили ответ), цепь останавливается.

Поскольку ваши заголовки установлены в app.all, они являются частью этапа маршрутизации. Поскольку вы прикрепляете router с app.use, это часть промежуточного этапа.

Однако, экспресс-маршрутизатор, который видит запрос OPTIONS с URL-адресом, соответствующим одному из своих маршрутов, делает что-то особенное. Если он дойдет до конца этого маршрутизатора без завершения запроса, он автоматически отправит ответ с набором заголовков Allow. Вот почему запрос никогда не попадает на ваш маршрут app.all, который устанавливает заголовки.

Предлагаемое исправление: установите заголовки (и отправьте ответ, если метод OPTIONS) в промежуточном программном обеспечении (app.use), а не маршруте. Вы также должны убедиться, что это промежуточное программное обеспечение подключено до маршрутизатора, который обрабатывает /login.

Итак, вместо app.all('/*', используйте app.use('/',. Убедитесь, что это произошло до app.use('/', router).

+0

Спасибо за ваш ответ, похоже, что это может сработать, но какие варианты должны я устанавливаю и где я должен делать? :) Не могли бы вы привести пример кода? –

+0

@MarcRasmussen Отредактировано с более четкими инструкциями в конце. Имеет ли это смысл? –

Смежные вопросы