如何在Django-auth生成的页面中启用https?

时间:2011-11-04 21:01:42

标签: django https django-authentication

使用Django-auth应用程序(Django版本1.3),我想让我的登录页面转到https://mysite.com/login/。目前,我正在使用:

# urls.py
from django.contrib.auth.views import login
urlpatterns = patterns('', url(r'^login/$', login, name='login-view'),)

# navbar.html
<li id="nav-login"><a href="{% url login-view %}" ><b>Login</b></a></li>

效果很好,但转到http://mysite.com/login/

当它反转视图名称时,有没有办法告诉Django-auth使用什么前缀(https)?我已经阅读了整个手册页,但没有找到任何涵盖它的内容。或者也许某种方式告诉url标签转到https?

或者是手动指定整个网址的唯一选项吗?我希望不是:)鉴于Django到目前为止有多强大,我无法相信它不具备这种能力 - 我必须忽视它。 :)

2 个答案:

答案 0 :(得分:10)

将OS环境变量HTTPS设置为on

您需要将操作系统环境变量HTTPS设置为'on',以便django将https添加到完全生成的链接(例如,与HttpRedirectRequest s)。如果您使用的是mod_wsgi,则可以添加以下行:

os.environ['HTTPS'] = "on"

wsgi script。您可以通过阅读django/http/__init__.py

来了解对此的需求
def build_absolute_uri(self, location=None):
    """
    Builds an absolute URI from the location and the variables available in
    this request. If no location is specified, the absolute URI is built on
    ``request.get_full_path()``.
    """
    if not location:
        location = self.get_full_path()
    if not absolute_http_url_re.match(location):
        current_uri = '%s://%s%s' % (self.is_secure() and 'https' or 'http',
                                     self.get_host(), self.path)
        location = urljoin(current_uri, location)
    return iri_to_uri(location)

def is_secure(self):
    return os.environ.get("HTTPS") == "on"

保护您的Cookie

settings.py中放行

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

和Cookie只能通过HTTPS连接发送。此外,您可能还需要SESSION_EXPIRE_AT_BROWSER_CLOSE=True。请注意,如果您使用的是旧版本的django(小于1.4),则没有安全CSRF cookie的设置。作为快速解决方案,您可以在会话Cookie安全(SESSION_COOKIE_SECURE=True)时通过编辑django/middleware/csrf.py让CSRF Coo​​kie安全:

class CsrfViewMiddleware(object):
   ...
   def process_response(self, request, response):
       ...
       response.set_cookie(settings.CSRF_COOKIE_NAME,
            request.META["CSRF_COOKIE"], max_age = 60 * 60 * 24 * 7 * 52,
            domain=settings.CSRF_COOKIE_DOMAIN,
            secure=settings.SESSION_COOKIE_SECURE or None)

在Web服务器

中对HTTPS进行直接HTTP请求

接下来,您需要一个重写规则,将http请求重定向到https,例如,在nginx中

server {
   listen 80;
   rewrite ^(.*) https://$host$1 permanent;
}

Django的reverse函数和url模板标签只返回相对链接;因此,如果您使用的是https页面,则您的链接会将您保留在https网站上。

答案 1 :(得分:1)

正如其他StackOverflow问题所示,您可以implement middleware自动将登录页面重定向到安全版本。

如果您对安全性非常认真,那么您应该将整个网站迁移到SSL。来自EFF How to Deploy HTTPS Correctly

  

您必须通过HTTPS提供整个应用程序域。使用HTTP 301或302对等效HTTPS资源的响应重定向HTTP请求。

     

有些网站运营商只提供基于HTTPS的登录页面,理由是只有用户的密码才是敏感的。这些网站的用户容易受到被动和主动攻击。