Ошибка аутентификации и междоменной ошибки в приложении Node – Express

Я разрабатываю приложение с использованием ember.js, которое работает на узле.

Теперь мне нужно вызвать некоторые внешние веб-службы и соответствующим образом создать свою домашнюю страницу (на основе ответа веб-службы).

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

Мой код app.js выглядит следующим образом:

var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
    app.use(express.errorHandler());
}

app.get('/', routes.index);

http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
});

Код домашней страницы (для простоты я удалил все ее представления и просто вызываю свой внешний веб-сервис при загрузке страницы)

<html>
<head>
    <title>Lets think..</title>
    <script src="./javascripts/libs/handlebars-1.0.0.js"></script>
    <script src="./javascripts/libs/jquery-1.9.1.js"></script>
    <script src="./javascripts/libs/ember-1.1.2.js"></script>
    <script>
        window.App = Ember.Application.create();
    </script>

    <script>
        $(window).load(function(){
            $.ajax({
                type: 'GET',
                url: 'http://vpn.domain_name.com/myServer/WebService/json/getInfo',
                data: {username: "user_name",password: "my_password"},
                success: function (data) {
                    console.log('sucess');
                },
                failure: function(error){
                    console.log('error');
                }
            });
        });
    </script>
</head>
<body>

</body>
</html>

Как сказано выше, я смог получить доступ к веб-сервису ниже (http://vpn.domain_name.com/myServer/WebService/json/getInfo) успешно из браузера (после проверки учетных данных).

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

"NetworkError: 401 Unauthorized - http://vpn.domain_name.com/myServer/WebService/json/getInfo?username=user_name&password=my_password"

При отладке через консоль Google Chrome:

XMLHttpRequest cannot load http://vpn.domain_name.com/myServer/WebService/json/getInfo?username=user_name&password=my_password. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

Я не уверен, вызваны ли вышеуказанные ошибки междоменным доступом или ошибкой базовой аутентификации http.

Я попробовал решения, предложенные в разделе Как разрешить CORS? и http://nthloop.com/blog/local-dev-with-nodejs-proxy/

Однако мне не удалось получить правильный ответ из моего кода. Может ли кто-нибудь помочь мне в этом.

Спасибо.


person Community    schedule 25.11.2013    source источник
comment
Используйте Jsonp вместо ajax. Проверьте stackoverflow.com/questions/ 5943630/   -  person Damodaran    schedule 25.11.2013
comment
Спасибо, Дамодаран. Однажды после добавления -- dataType: 'jsonp' в мой вызов ajax я смог успешно получить ответ. Спасибо за это. Однако теперь я получаю еще одну странную проблему. В первый раз, когда я запускаю свое приложение (веб-сайт), оно просит меня указать имя пользователя и пароль веб-службы при загрузке страницы.. один раз после того, как я предоставлю действительные учетные данные, я могу успешно получить доступ к веб-сайту. Как я могу удалить этот запрос аутентификации. Другими словами, я передаю эти учетные данные (имя пользователя и пароль) в своем вызове ajax. Почему это не влияет? Предложения, пожалуйста. Спасибо еще раз.   -  person    schedule 25.11.2013


Ответы (2)


(больше ответа на комментарий, вопрос не в этом)

Если вы хотите передать учетные данные для базовой аутентификации с помощью $.ajax:

$.ajax({
  type      : 'GET',
  url       : 'http://vpn.domain_name.com/myServer/WebService/json/getInfo',
  username  : 'user_name',
  password  : 'my_password',
  success   : function (data) {
    console.log('success');
  },
  failure   : function(error){
    console.log('error');
  }
});

(вместо передачи username и password в качестве параметров URL с data).

person robertklep    schedule 25.11.2013
comment
Спасибо за ответ. Как Дамодаран ответил выше, после использования dataType: 'jsonp' в вызове ajax я могу успешно получить ответ. Однако, когда я запускаю свое приложение, оно впервые просит меня указать имя пользователя и пароль веб-сервиса - на странице load (базовая аутентификация). один раз после того, как я предоставлю действительные учетные данные, я смогу успешно получить доступ к веб-сайту. Как я могу удалить этот первый запрос аутентификации. Другими словами, я передаю эти учетные данные (имя_пользователя и пароль) в самом вызове ajax. Тогда почему меня впервые просят предоставить учетные данные - person ; 25.11.2013
comment
@Kamal, ты заметил, как мой код отличается от твоего исходного кода? - person robertklep; 25.11.2013
comment
Я получил ту же ошибку, когда я передаю имя пользователя и пароль в качестве параметров URL с данными или при передаче их отдельно - как упоминалось вами :( Только когда я включил dataType: 'jsonp' в свой вызов ajax, эта проблема исправлена. Однако получение проблема с аутентификацией в первый раз. - person ; 25.11.2013
comment
@Kamal Ты сам создал веб-сервисы? если да, можете ли вы показать код, который обрабатывает аутентификацию? - person robertklep; 25.11.2013
comment
Нет. Я не создавал эти веб-сервисы. Кроме того, у меня нет доступа к этому коду веб-сервисов. Извиняюсь. Я считаю, что базовая HTTP-аутентификация, приведенная выше, верна. Я думаю, что запрос имени пользователя и пароля должен быть только базового типа HTTP-аутентификации. пожалуйста, поправьте меня, если я ошибаюсь. - person ; 25.11.2013
comment
@Kamal Я протестировал код с базовой структурой аутентификации, и он работает нормально. Возможно, веб-служба прибегает к какой-то другой форме проверки аутентификации, когда запрос выполняется с использованием JSONP, но я просто предполагаю... - person robertklep; 25.11.2013
comment
Спасибо. Я свяжусь с автором этого веб-сервиса, чтобы найти причину. Кроме того, я использую JSONP только для решения междоменной проблемы. Тем не менее, у меня впервые возникла проблема с базовой проверкой подлинности и проблемы с ответом (SyntaxError: отсутствует; перед утверждением в моем элементе ответа). По приведенной ниже ссылке я обнаружил, что: stackoverflow.com/questions/19456146/, если мы используем JSONP вместо JSON, мы получим эту проблему. Поэтому я чувствую, что этот веб-сервис не поддерживает JSONP. Ищу альтернативное решение. Можешь ли ты направить меня? - person ; 26.11.2013
comment
@Kamal, если веб-сервис не поддерживает JSONP или CORS, вам не повезло, если только вы не настроили для него локальный прокси-сервер. - person robertklep; 26.11.2013
comment
Да, вы правы, Робертклеп. Я использовал http-прокси, и теперь все работает нормально. Включил мой код ниже. Спасибо. - person ; 26.11.2013

Первоначально я использовал JSONP, потому что это действительно простой способ обойти политику одного и того же домена XMLHttpRequest. Тем не менее, веб-сервисы, к которым я обращаюсь, вызвали несколько проблем с типом данных JSONP (базовая HTTP-аутентификация терпит неудачу в первый раз, и ответ выдает странную ошибку SyntaxError:missing ; before statement). Поскольку у меня нет большого контроля над веб-сервисами для работы с JSONP, я решил отказаться от опции JSONP и приступил к методу http-proxy для решения проблемы междоменного доступа.

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

(1) Установлен http-proxy npm

(2) Добавлены следующие строки в app.js

var httpProxy = require('http-proxy');

var endpoint  = {
    host:   'IP_ADDRESS_OR_DOMAIN_NAME', //of webservice
    port:   80, 
    prefix: '/myServer/WebService/json'  //all my webservices are accessed through this path
}

app.use(function(req, res) {
    if (req.url.indexOf(endpoint.prefix) === 0) {
        proxy.proxyRequest(req, res, endpoint);
    }
});

(3) Мой вызов ajax будет:

$(window).load(function(){
            $.ajax({
                type: 'GET',
                url: '/myServer/WebService/json/getInfo',
                username: "user_name",
                password: "password",
                success: function (data) {
                    console.log('sucess');
                    console.log(data);
                },
                failure: function(error){
                    console.log('error');
                }
            });
        });

Здесь: /getInfo — это веб-сервис (с базовой HTTP-аутентификацией).

Надеюсь это поможет!

Спасибо.

person Community    schedule 25.11.2013