Django将HTTPS重定向到HTTP

4

我有一个正在运行的 Django 电商网站,并购买并安装了 SSL 证书。

我已经添加了一个 VirtualHost 条目:

<VirtualHost *:443>
        #Basic setup
        ServerAdmin blah@test.com

        ServerName test.com
        ServerAlias www.test.com

        Alias /media/admin/ /home/test/public_html/test/release/env/lib/python2.6/dist-packages/django/contrib/admin/media/
        Alias /static/ /home/test/public_html/test/release/static/
        Alias /media/ /home/test/public_html/test/release/media/

        <Directory /home/test/public_html/test/release/>
            Order deny,allow
            Allow from all
        </Directory>
        RewriteEngine On

        LogLevel warn
        ErrorLog  /home/test/public_html/test/logs/error.log
        CustomLog /home/test/public_html/test/logs/access.log combined

        WSGIDaemonProcess test user=www-data group=www-data threads=20 processes=2
        WSGIProcessGroup test_ssl

        WSGIScriptAlias / /home/test/public_html/test/release/apache/test.wsgi

        SSLEngine On
        SSLCertificateFile /etc/apache2/ssl/test.com.crt
        SSLCertificateChainFile /etc/apache2/ssl/gs_root.pem
        SSLCertificateKeyFile /etc/apache2/ssl/www.test.com.key
</VirtualHost>

这是urls.py文件:

from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
from django.conf import settings

from gallery.models import LOCATIONS, Photo

admin.autodiscover()

from satchmo_store.urls import urlpatterns as satchmo_urls

from satchmo_store.shop.views.sitemaps import sitemaps
from cms.sitemaps import CMSSitemap
sitemaps['pages'] = CMSSitemap

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^search/', include('haystack.urls')),

    # Include satchmo urls. Unfortunately, this also includes it's own
    # /admin/ and everything else.
    url(r'^shop/', include(satchmo_urls)), 
    url(r'^sitemap\.xml/?$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),

    url(r'events/gallery/(.*)/(.*)/$', 'gallery.views.events_image'),
    url(r'locations/view-all/(.*)/$', 'gallery.views.locations_image'),
    url(r'locations/view-all/$', 'gallery.views.locations_view_all',{
            'queryset':Photo.objects.filter(gallery__category=LOCATIONS).distinct()}),
    url(r'^contact-us/', include('contact_form.urls')),
    url(r'^', include('cms.urls')),
)

if settings.DEBUG:
    urlpatterns = patterns('',
        (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
        (r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
        (r'^404/$', 'django.views.defaults.page_not_found'),
        (r'^500/$', 'django.views.defaults.server_error'),
    ) + urlpatterns

还有一个非ssl的conf,它工作得很好。

每当我请求站点的HTTPS版本时,都会收到302头响应,该响应重定向到HTTP版本。

在apache conf中没有明确说明转到80端口的重定向。

我已经困扰了一段时间,任何帮助都将是巨大的!

谢谢


cms/urls.py 中是否有任何重定向的内容? - cubetwo1729
我们正在使用DjangoCMS-里面什么都没有... - Simon
3个回答

7
您可能已经修复了它,这可能是一个完全不同的问题,但我刚刚遇到了一些听起来有些相似的东西,因为我没有找到解决您问题的答案,所以我认为发帖回复可能是值得的(尽管我有301,而你有302)。
我正在运行一个Django网站(Django 1.6.1),使用gunicorn在nginx后面。因此,nginx执行SSL。环境变量HTTPS设置为on。
当我设置一个没有http-to-https重定向的测试服务器时,我注意到一些请求最终被重定向到http地址 - 类似于您描述的情况,但在我的情况下,只是针对一个特定的链接。在查看请求和响应头之后,我发现: 初始请求https://example.org/test通过Django/gunicorn重定向到http://exmaple.org/test/,状态码为301 MOVED PERMANENTLY。然后,nginx响应为400 Bad Request - The plain HTTP request was sent to HTTPS port.

我很快就发现了一个以前没有注意过的设置: APPEND_SLASH (https://docs.djangoproject.com/en/1.6/ref/settings/#std:setting-APPEND_SLASH),默认值为True

在我的settings.py文件中添加APPEND_SLASH = False后,对https://example.org/test的请求会返回404 NOT FOUND响应,而不是重定向到http。因此,看来APPEND_SLASH不遵守HTTP环境变量设置 - 我猜配置SECURE_PROXY_SSL_HEADER(https://docs.djangoproject.com/en/1.6/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER)可以解决这个问题,但我还没有测试过。

顺便说一下,我遇到链接“错误”的原因是模板中的硬编码链接。避免这样的链接的简单方法是使用内置的{% url ... %} 模板标签(https://docs.djangoproject.com/en/1.6/ref/templates/builtins/#url)。也许这可以帮助你或其他人想知道为什么Django有时会从https重定向到http。

3
设置SECURE_PROXY_SSL_HEADER解决了我的问题。 - Nathan
我设置了 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),但在某些情况下仍然会重定向到HTTP。我正在使用 Django 1.6.5 并在 AWS 上部署,AWS 负载均衡器将 HTTPS“代理”到非 HTTPS。不幸的是,我需要 APPEND_SLASH - jweyrich
如果您设置了HTTP_X_FORWARDED_PROTO并正确配置了Web服务器,通常应该可以正常工作。也许负载均衡器与标头有些冲突? - goetz

1
我知道这是一个老问题,但我刚刚花了几个小时搜索解决方法,最终在这里发布我的解决方案。我像原帖作者一样使用Satchmo,它有一个中间件类satchmo_store.shop.SSLMiddleware.SSLRedirect,默认情况下发送一个重定向,如原问题所述,从https到http,使用302头响应。注释掉MIDDLEWARE_CLASSES中的这行可以解决问题,如果有人想完全在https上运行,那么这可能是可以接受的,但文档http://satchmo.readthedocs.org/en/latest/configuration.html#ssl解释了如何正确使用它,这是我要尝试的。

0

我能想到的唯一可能是你在数据库中的站点设置。如果你在Site对象中放置了一个明确的端口号……你能在管理员界面看一下吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接