意外302 /从HTTPS重定向到HTTP导致'不安全内容'javascript错误

时间:2012-12-20 16:20:48

标签: ssl devise ruby-on-rails-3.2 extjs4.1

我有一个带有Ruby on Rails 3.2后端的ExtJS 4.1应用程序,使用Devise(启用了Timeoutable)进行身份验证,会话管理。

此问题发生在服务器上,其中应用程序仅通过SSL提供。 Nginx将任何非安全请求重定向到https网址。

问题在于,当Devise会话超时时,在我的情况下,15分钟后,任何AJAX请求被发送/重定向到 http ://myapp.com/controller?params,而不是 https ://myapp.com/controller?params,就像通常那样。

我有客户端代码,在非SSL设置中可以很好地捕获潜在的会话过期问题,并重定向到登录页面,并显示会话已超时的消息。这是一种基于以下事实的黑客:当会话超时后发出请求时,会返回“无效的JSON字符串”错误消息。该错误包含“登录”页面的HTML,因为当用户登录时应该是json的响应成为应用程序应在会话超时时重定向到的“登录”页面。这段代码在我的 Ext.application 启动方法中:

launch:                             function () {

    Ext.Error.handle = function (err) {

        $.post('/logs', {message:err.msg});

        if (err.msg.indexOf("invalid JSON String") != -1 && err.msg.indexOf("<!DOCTYPE html>") != -1) {

            if (err.msg.indexOf("MyApp_Login") != -1)
                document.location.href = "/logout?timeout=1";
            else
                document.location.href = "/logout?error=1";

        } else {

            gritter(3, "ERROR:", "A client-side error has occurred. If this issue persists, please contact your system administrator.");

            if (Ext.isWebKit) console.log(err);

        }

    }

    if (user_signed_in == true) {

        Ext.require('MyDesktop.App');
        Ext.require('Ext.tab.*');

        _myDesktopApp = Ext.create('MyDesktop.App');

        Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));

    }

}

正如我上面所说,通过非安全套接字,应用程序会检测到指示会话超时的控制器请求(或更精确的响应),并采取适当的措施。但是在我的服务器上,通过SSL,由于某种原因,一旦会话过期,控制器调用最终会超过http而不是https。在Chrome中导致这样的错误:

The page at https://server.myapp.com/ displayed insecure content from http://server.app.com/campaign_components_contacts.json?authenticity_token=1vokGHUpsi5w3b3P8mrfUpEGx19hrHJpsCzPayofM7c%3D&campaign_id=2&component_id=2&contact_id=1536&format=json

这可能是ExtJS的一项功能,它会在通过SSL检测到问题时尝试非安全呼叫吗?或者Rails的一些功能?我敢肯定它不是,但只是抛弃了我头脑中的一些东西。

编辑:

我已经能够在开发环境中使用 - ssl 开关在本地测试场景。启动服务器后,我浏览到

https://localhost:3000

没有问题。一旦Devise会话到期,任何json请求都会按预期触发重定向登录,并通过http工作。

因此,此问题中描述的问题仅出现在我的服务器上,可能与我的NGINX配置设置方式有关。

我还会在本地预编译应用程序并使用prod环境选项运行,只是为了确保它与dev和prod之间的区别无关。

1 个答案:

答案 0 :(得分:2)

哇,原来与Devise会话超时,Rails或ExtJS无关。

最后通过调整NGINX配置来解决这个问题,根据文档,这可能对所使用的版本是正确的,但结果却导致了这个问题。

当前的ssl服务器位:

server {
            listen 443;
            ssl on;
            ssl_certificate      /srv/ssl/server.myapp.com.combined.crt;
            ssl_certificate_key  /srv/ssl/server.myapp.com.key;
            server_name server.myapp.com;
            root /var/www/myapp/current/public;
            passenger_enabled on;
            rails_env myapp_staging;
    }

我之前:

server {
            listen 443 ssl;
            ssl_certificate      /srv/ssl/server.myapp.com.combined.crt;
            ssl_certificate_key  /srv/ssl/server.myapp.com.key;
            server_name server.myapp.com;
            root /var/www/myapp/current/public;
            passenger_enabled on;
            rails_env myapp_staging;
    }

区别在于分裂

listen 443 ssl;

成:

listen 443;
ssl on;