【问题标题】:Https Nginx NodeJS SocketIO And CORS request failedHttps Nginx NodeJS SocketIO 和 CORS 请求失败
【发布时间】:2015-05-22 11:34:33
【问题描述】:

这是我的问题,

上下文:

我有一个 NGinx 服务器正在工作。 NGinx 使用证书来启用 HTTPS。从那里没有问题。

我有一个 NodeJS 服务器正在工作,它应该使用 socketIO 来处理 websockets。

我正在 Mozilla Firefox 上进行测试(这可能不是最好的...)

应用首先在 HTTP 上,一切正常。现在全部切换到 HTTPS,我面临一个“跨域”问题。

我已经尝试了几种解决方案,但没有一个对我有用...我将在帖子末尾解释我尝试了什么。

首先,让我向您展示相关文件,nodeJS 的 server.js,NGinx 服务器的 nginx.conf,以及应该连接 websocket 的“客户端脚本”。

server.js - NodeJS

var app = require('express')();
var fs = require('fs');
var https = require('https');
var _ = require('underscore');
var socketio = require('socket.io');
var options = {
    key: fs.readFileSync('/ssl/file.key'),
    cert: fs.readFileSync('/ssl/file.crt')
};
var server = https.createServer(options).listen(9001,function(){
    console.log("SERVER LISTENING");
});
io = socketio.listen(server,{origins:'*:*'});

var connectedSockets = {};

_.each(io.nsps, function(nsp){
  nsp.on('connect', function(socket){
    if (!socket.auth) {
      delete nsp.connected[socket.id];
    }
  });
});

function checkAuthToken(token,callback){
    callback(null,true);
}

io.on('connection',function(socket){
    socket.broadcast.emit('hi');
    socket.on('disconnect',function(){
        console.log('a user disconnected');
    });
    socket.on('chat message',function(msg){
        io.emit('chat message',msg);
    });
    socket.on('authenticate', function(data){
      checkAuthToken(data.token, function(err, success){
        if (!err && success){
          socket.auth = true;
          _.each(io.nsps, function(nsp) {
            if(_.findWhere(nsp.sockets, {id: socket.id})) {
              nsp.connected[socket.id] = socket;
            }
          });
        }
      });
    });
});

这是一个“简单”的聊天应用程序,需要完成一些事情,例如应该检查身份验证的脚本......

nginx.conf - NGinx 服务器配置

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    map $http_upgrade $connection_upgragde {
        default upgrade;
        '' close;
    }
    sendfile        on;
    server {
        listen 80;
        server_name 192.168.100.22;
        rewrite ^ https://$http_host$request_uri? permanent;
    }
    server {
        listen       443;
        ssl on;
        ssl_certificate /ssl/file.crt;
        ssl_certificate_key /ssl/file.key;
        server_name  192.168.100.22;
        root E:/www;
        index index.php index.html index.htm;
        add_header Access-Control-Allow-Origin *;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
        proxy_set_header X-Forwarded-For $remote_addr;
        server_tokens off;
        charset utf-8;
        error_page   500 502 503 504  /50x.html;
        location ~ \.php$ {
            try_files $uri =404;
            include /Nginx/nginx-1.8.0/conf/fastcgi_params;
            fastcgi_param HTTPS on;
            fastcgi_param HTTP_SCHEME https;
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
}

Client.js - index.php 中的连接脚本

<script src="./jquery-1.11.1.js"></script>
<script src="./socket.io-1.3.5.js"></script>
<script>
  var socket = io('wss://192.168.100.22:9001');
  $("form").submit(function(){
    socket.emit('chat message',$('#m').val());
    $('#m').val('');
    return false;
  });
  socket.on('connect', function(){
      socket.emit('authenticate', {token: 456456456,rights:'any'});
    });
  socket.on('chat message', function(msg){
    $('#messages').append($('<li>').text(msg));
  });
  socket.on('hi',function(){
    $('#messages').append($('<li>').text('connection'));
  });
</script>

服务器位于 192.168.100.22 IP

Nginx 监听 80 & 443 并将所有流量重定向到 443 (https)

通过nginx访问文件夹就ok了,当前聊天测试位于192.168.100.22/websocks/index.php

错误信息如下:

GET https://192.168.100.22:9001/socket.io/?EIO=3&transport=polling&t=1432131062725-0 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://192.168.100.22:9001/socket.io/?EIO=3&transport=polling&t=1432131062725-0. Reason: CORS request failed

实际上,我已经尝试将它添加到 nodejs 脚本中:

https.globalAgent.options.rejectUnauthorized = false;
app.get('*',function(req,res,next){
    res.header("Access-Control-Allow-Origin","*");
    res.header("Access-Control-Allow-Headers","X-Requested-With");
    next();
});

但还没有任何效果...

感谢阅读/帮助

【问题讨论】:

  • 在我的情况下,错误的 ssl 证书安装导致了这个问题。

标签: javascript node.js nginx https cors


【解决方案1】:

验证您的 SSL 证书有效且名称与您的域匹配。看起来您使用的是 IP 地址而不是证书的域名。当 Firefox 抱怨证书时,我看到了 CORS 错误。

【讨论】:

  • 嗯,你似乎在帮助我解决这个问题的正确方法。正如您所说,证书是自签名的,实际上是为服务器 IP 地址生成的。这意味着,在证书中,CN 匹配 192.168.100.22。那我该怎么做才能解决这个问题?如果我将CN设置为域名而不是IP,它会起作用吗?考虑到我在开发虚拟机上,设置一个域名(虚构的,因为我还没有)而不是 IP 是可能的吗?和工作?感谢您的帮助
  • 是的,如果您在浏览器中访问此 IP 并看到证书警告,您可以在浏览器设置中覆盖它以忽略警告。否则,我会为证书的 CN 使用域名而不是 IP 地址。更新您的本地主机文件以将此虚拟域名指向开发 IP。然后在浏览器中打开此域名并确认您没有收到任何证书警告,然后再继续。
猜你喜欢
  • 2014-02-14
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
相关资源
最近更新 更多