【问题标题】:Authentication and cross domain error from a Node - Express application来自 Node - Express 应用程序的身份验证和跨域错误
【发布时间】:2013-11-25 12:38:10
【问题描述】:

我正在使用运行在节点上的 ember.js 开发一个应用程序。

现在,我必须调用一些外部 Web 服务并相应地构建我的主页(基于 Web 服务响应)。

  • 这些 web 服务在一些外部服务器(不同的域)中运行。目前我正在本地环境中运行我的网站。
  • 身份验证:只有在提供有效凭据后,用户才能访问这些网络服务。也就是说,如果我尝试从浏览器访问此 Web 服务,首先它会要求提供用户名和密码。如果这些凭据有效(服务器端验证),它将返回响应 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'));
});

主页代码(为简单起见,我删除了它的所有视图,只在页面加载时调用我的外部 Web 服务)

<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>

如上所述,我能够从浏览器成功访问以下 Web 服务 (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基本认证错误。

我尝试了How to allow CORS?http://nthloop.com/blog/local-dev-with-nodejs-proxy/ 中建议的解决方案

但是,我无法从我的代码中检索到正确的响应。谁能指导我。

谢谢。

【问题讨论】:

  • 使用 Jsonp 而不是 ajax。检查stackoverflow.com/questions/5943630/…
  • 感谢 Damodaran.. 在我的 ajax 调用中添加 -- dataType: 'jsonp' 后,我就能够成功检索响应。感谢那。但是,现在我遇到了另一个奇怪的问题。第一次运行我的应用程序(网站)时,它要求我在页面加载时提供网络服务的用户名和密码。一旦我提供了有效的凭据,我就可以成功访问网站。如何删除此身份验证请求。换句话说,我在我的 ajax 调用中传递了这些凭据(用户名和密码)。为什么不影响?请提出建议。再次感谢。

标签: node.js ember.js express node-http-proxy


【解决方案1】:

(更多是the comment的答案,不是实际问题)

如果您想使用$.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');
  }
});

(而不是将usernamepassword 作为URL 参数与data 一起传递)。

【讨论】:

  • 感谢您的回复。正如 Damodaran 上面回答的那样,在 ajax 调用中使用 dataType: 'jsonp' 后,我能够成功检索响应。但是,当我运行我的应用程序时,它要求我第一次提供 web 服务的用户名和密码 - 在页面上加载(基本身份验证)。提供有效凭据后,我就可以成功访问网站。如何删除此首次身份验证请求。换句话说,我在我的 ajax 调用本身中传递了这些凭据(用户名和密码)。那么为什么我第一次被要求提供凭据
  • @Kamal 您是否注意到我的代码与您的原始代码有何不同?
  • 当我将用户名和密码作为带有数据的 URL 参数传递或单独传递它们时,我得到了同样的错误 - 正如你所提到的那样:( 仅当我在我的 ajax 调用中包含 dataType: 'jsonp' 时,此问题已修复。但是,遇到第一次身份验证问题。
  • @Kamal 我用一个基本的身份验证框架测试了代码,它工作正常。当使用 JSONP 执行请求时,Web 服务可能会退回到其他形式的身份验证检查,但我只是在这里猜测......
  • @Kamal 如果网络服务不支持 JSONP CORS,那么你就很不走运了,除非你为它设置了本地代理。
【解决方案2】:

我最初使用 JSONP,因为它确实是一个简单的技巧来克服 XMLHttpRequest 同域策略。但是,我正在访问的 Web 服务很少出现 JSONP 数据类型的问题(基本的 http 认证第一次失败,响应抛出一个奇怪的错误 SyntaxError: missing ; before statement)。由于我对使用 JSONP 的 Web 服务没有太多控制权,因此考虑放弃 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 是 web 服务(带有基本的 http 身份验证)。

希望这会有所帮助!

谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 2015-07-03
    • 2018-02-05
    • 1970-01-01
    • 2022-05-26
    • 2013-10-26
    相关资源
    最近更新 更多