Аутентификация и междоменная ошибка из приложения 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/
Однако я не смог получить правильный ответ из моего кода. Может кто-нибудь, пожалуйста, направьте меня в этом.
Благодарю вас.
2 ответа
Первоначально я использовал JSONP, потому что это действительно простой способ преодолеть XMLHttpRequest той же политики домена. Тем не менее, веб-сервисы, к которым я обращаюсь, подняли несколько проблем с типом данных JSONP (базовая http-аутентификация завершается неудачно в первый раз, и в ответ выдается странная ошибка SyntaxError: отсутствует; оператор before). Поскольку у меня нет большого контроля над веб-сервисами для работы с JSONP, я решил отказаться от опции JSONP и перешел к методу http-proxy для решения междоменной проблемы.
Внесены следующие изменения в код клиента, и теперь я смог успешно получить доступ к веб-сервисам.
(1) Установлен http-прокси 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-аутентификацией).
Надеюсь это поможет!
Благодарю.
(больше ответ на комментарий, а не на реальный вопрос)
Если вы хотите передать учетные данные для базовой аутентификации, используя $.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
).