[[Django]]로 [[SSL]]서비스하기.

[[Apache]] 인증서 설정까지 다 끝났다는 가정하에,

== SSL 적용 ==

데이터 암호화가 필요한 폼 제출 부분의 action 링크를 https 로 수정한다. (보통은 이 작업만 하면 끝이지만,) 

일반적으로 Django에서는 같은 view가 폼 표시와 폼 처리를 보통 같이 수행한다. 그러다 보니, 폼 체크 실패 이후, 계속 https 로 연결된다. 

== SSL redirect 미들웨어 적용 ==

[[http://www.djangosnippets.org/snippets/85/|SSL Middleware]]를 적용하면, urls.py 에 표시한 view에 대해 자동으로 SSL redirection 을 수행한 뒤, 자동으로 비 보안 연결로 복귀된다.

하지만, 위 코드는 SSL 포트가 443으로 변하지 않을 경우에만 동작한다. 만일 다른 SSL 포트를 써야 한다면 settings.py 에 SSL_PORT 를 명기한 뒤 아래처럼,

{{{#!python
__license__ = "Python"
__copyright__ = "Copyright (C) 2007, Stephen Zabel"
__author__ = "Stephen Zabel - sjzabel@gmail.com"
__contributors__ = "Jay Parlar - parlar@gmail.com"

from django.conf import settings
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, get_host

SSL = 'SSL'

class SSLRedirect:
    def process_view(self, request, view_func, view_args, view_kwargs):
        if SSL in view_kwargs:
            secure = view_kwargs[SSL]
            del view_kwargs[SSL]
        else:
            secure = False

        if not secure == self._is_secure(request):
            return self._redirect(request, secure)

    def _is_secure(self, request):
        if request.is_secure():
	    return True

        #Handle the Webfaction case until this gets resolved in the request.is_secure()
        if 'HTTP_X_FORWARDED_SSL' in request.META:
            return request.META['HTTP_X_FORWARDED_SSL'] == 'on'

        return False

    def _redirect(self, request, secure):
        protocol = secure and "https" or "http"
        ssl_port = ''
        if hasattr(settings, 'SSL_PORT'):
            ssl_port = ":%s" % settings.SSL_PORT
        if protocol == 'http':
            ssl_port = ''
        newurl = "%s://%s%s%s" % (
                protocol,get_host(request).split(':')[0],
                ssl_port,
                request.get_full_path(),
                )
        if settings.DEBUG and request.method == 'POST':
            raise RuntimeError, \
        """Django can't perform a SSL redirect while maintaining POST data.
           Please structure your views so that redirects only occur during GETs."""

        return HttpResponsePermanentRedirect(newurl)

}}}