BLOG ARTICLE Django | 6 ARTICLE FOUND

  1. 2012.07.25 Django의 cache 사용
  2. 2012.07.25 decorator 만들기
  3. 2012.07.25 hash(digest) 호출
  4. 2012.07.25 request의 값 처리
  5. 2012.07.25 CSRF token 생성
  6. 2012.07.13 Django의 session 처리


Django에서는 Cache 기능도 제공한다.

memcached, DB, 로컬메모리, 파일(?) 등의 종류를 제공하는데 각각 장단점이 있다.


memcached는 외부 캐쉬프로세스를 띄워 놓고, 거기에 

DB 방식의 경우는 여러 인스턴스가 동일한 DB를 바라보니까 모두 같은 데이터를 사용할 수 있겠지만, 속도는 좀 느릴 것이고,

로컬메모리 방식은 각 인스턴스가 자기 메모리에 각각 cache하니까 다른 데이터를 사용할 수 있는 가능성이 있겠지만, 속도는 빠를 것이고,

파일은 DB와 비슷할 것 같다.


나는 설정할 것이 별로 없고 빠른 로컬메모리 방식을 선택했다.

거의 변경가능성이 희박한 데이터를 cache한다면, 로컬메모리 방식이 가장 좋을 듯하다.


일단 settings.py에 cache를 사용하겠다고 설정을 해 줘야 한다.

CACHES = {

    'default': {

        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',

        'TIMEOUT': 3600,

    }

}


이렇게 하면, Local Memory 방식의 cache를 사용하고, 3600초(1분) 단위로 cache 들어간 데이터가 삭제한다는 뜻이다.


다음은 코드에서 사용하기만 하면 된다.

from django.core.cache import cache


cache.set('key', value)
cached_val = cache.get('key')


아주 간단하다.

cache를 import 하고, cache.set으로 집어 넣고, cache.get으로 꺼낸다.


이것을 응용해서 구현을 한다면,

get해서 나온 값이 None이면 넣을 데이터를 조회하거나 만들어서 set을 하면 되겠다.

cache에는 어떤 값이나 객체도 넣을 수 있는 것 같다.


이외에도 get_many로 한번에 여러 key를 리스트로 던지면, key와 value로 구성된 dict로 리턴하는 함수도 있고,

cache에서 내용을 지우는 delete, 전체를 지우는 clear 함수도 있다.


다시 매뉴얼을 보니 화면단에서도 cache를 사용할 수 있는데, 필요한 분들은 매뉴얼을 보시길...


'Python_Django' 카테고리의 다른 글

decorator 만들기  (0) 2012.07.25
hash(digest) 호출  (0) 2012.07.25
request의 값 처리  (0) 2012.07.25
CSRF token 생성  (0) 2012.07.25
Django의 session 처리  (0) 2012.07.13
AND

decorator 만들기

Python_Django 2012. 7. 25. 10:50


Django에서 기본으로 제공하는 사용자정보나 권한정보를 이용하지 않고 별도의 테이블을 만들어서 사용할 경우,

decorator를 만들어서 login_required, permission_required 를 구현할 수 있다.


test.common.decorators.py

from django.db import connection

from django.http import HttpResponseRedirect


# view_func : @login_required가 붙어 있는 함수

# request : view_func의 첫번째 인자

def login_required(view_func, login_url='/test/user/login/?autherr=login'):

    def decorator(request, *args, **kwargs):

        # 로그인된 상태이므로 원래 view 함수를 실행한다

        if 'userid' in request.session:

            return view_func(request, *args, **kwargs)

        # 로그인을 하지 않았으므로, 로그인페이지로 redirect

        else:

            return HttpResponseRedirect(login_url)

    return decorator


# view_func : @permission_required가 붙어 있는 함수

# request : view_func의 첫번째 인자

def permission_required(view_func, login_url='/test/user/login/?autherr=perm'):

    def decorator(request, *args, **kwargs):

        if has_permission(request):

            return view_func(request, *args, **kwargs)

        else:

            return HttpResponseRedirect(login_url)

    return decorator


views.py

from test.common.decorators import login_required, permission_required


@login_required

@permission_required

def sample_page(request):

    "샘플 페이지"

    return render_to_response('test/sample_page.html',   # Template 페이지 

                              RequestContext(request))   # request를 넘김


먼저 login_required를 보면,(로그인 여부 체크)

파라미터로 받는 view_func는 아래 views.py에서 sample_page 함수이다.

그리고, 그 안에 있는 decorator 함수의 request 파라미터는 views.py의 sample_page 함수의 request 파라미터가 넘어간다.

결국, 세션 안에 userid 값이 있으면 로그인된 상태로 판단하여 원래의 view_func(sample_page함수)가 수행되고,

아니면 login_url 페이지로 리다이렉트된다.

나는 login_url의 autherr이라는 get 방식 파라미터를 넘겼는데, login_url 페이지의 상단에서 이 값이 넘어오면 어떤 권한 에러가 났는지 나타내 주기 위해 추가했다.

여기서는 세션에 있는 userid 값으로 로그인여부를 체크하였기 때문에, 로그아웃시에는 반드시 request.session.clear() 함수를 호출해서 세션에 있는 값들을 모두 삭제해 줘야 한다.


permission_required를 보면,(해당 메뉴에 대한 권한여부 체크)

login_required와 같은 구조인데, boolean값을 리턴하는 has_permission 함수를 이용해서 권한이 있는지 확인한다.

나는 권한에 대한 메뉴리스트를 최초에는 DB에서 조회해서 있으면 True를, 없으면 False를 리턴하도록 구현했는데,

성능 문제가 발생할 것 같아, DB에서 조회한 내용을 Django에서 제공하는 Cache에 넣도록 수정했다.

이런 내용은 업무성격에 따라 처리하면 되겠다.


views.py에서는

로그인여부와 권한여부를 체크해야 하는 함수의 바로 위에 @login_required와 @permission_required를 붙여 주기만 하면 된다. 물론, 필요에 따라 둘 중에 하나만 사용해도 된다.


'Python_Django' 카테고리의 다른 글

Django의 cache 사용  (0) 2012.07.25
hash(digest) 호출  (0) 2012.07.25
request의 값 처리  (0) 2012.07.25
CSRF token 생성  (0) 2012.07.25
Django의 session 처리  (0) 2012.07.13
AND

hash(digest) 호출

Python_Django 2012. 7. 25. 10:23


요즘 패스워드를 저장할 때, 복호화가 불가능하도록 hash 함수를 이용해 패스워드를 저장한다.

이런 함수를 Django에서도 제공한다.

아래는 그 사용 예.


from django.utils.hashcompat import hashlib


def digest_password(password):

    return hashlib.sha256(password).hexdigest() # 64자리 문자열 리턴


sha256 외에도 여러 함수를 제공하는데, 그 아래는 공격이 가능하다고 하니 안전하게 256 이상을 사용하는 것이 좋을 것 같다.

※ 혹시, 이걸로 어떻게 하는지 잘 모르는 분들을 위해 간단한 패스워드 처리 방법.
1. 패스워드를 위의 함수를 이용해서 처리한 후 DB에 저장
2. 사용자가 로그인시 입력한 패스워드를 위의 함수를 이용해 변환한 후, DB에 있는 변환된 값과 비교해서
   같으면 로그인 성공, 다르면 틀린 패스워드

'Python_Django' 카테고리의 다른 글

Django의 cache 사용  (0) 2012.07.25
decorator 만들기  (0) 2012.07.25
request의 값 처리  (0) 2012.07.25
CSRF token 생성  (0) 2012.07.25
Django의 session 처리  (0) 2012.07.13
AND


request로부터 값을 얻을 때는 방식(POST,GET)에 따라 다른 클래스를 통해서 값을 얻어야 한다.


POST방식, (python코드에선 다음와 같이 방식 확인 : request.method == 'POST')


1. python에서

   request.POST['user_id']


2. template에서

   {{ request.POST.user_id }}


request.POST가 dictionary 객체



GET 방식이면, request.GET 이고 나머지는 동일


'Python_Django' 카테고리의 다른 글

Django의 cache 사용  (0) 2012.07.25
decorator 만들기  (0) 2012.07.25
hash(digest) 호출  (0) 2012.07.25
CSRF token 생성  (0) 2012.07.25
Django의 session 처리  (0) 2012.07.13
AND

CSRF token 생성

Python_Django 2012. 7. 25. 10:16


공격방법 중에 CSRF 관련된 것이 있는 모양인데(어떻게 하는지는 잘 모르겠고),

Django에선 이런 걸 막는데 필요한 정보가 넘어 오지 않으면 처리 중에 에러를 발생시킨다.

그러니까, 반드시 아래의 절차를 따라서 submit할 때 csrf token를 서버로 보내 줘야 한다.


POST방식으로 데이터를 전송하려면, 입력하는 화면에서 아래와 같은 코드가 추가되어야 한다.


1. view에서 request에 대해 csrf 정보 추가

from django.core.context_processors import csrf


def show_userinfo3(request):

    c = {}

    c.update(csrf(request))

    return render_to_response('user/input.html',c)


위와 같이 귀찮게 매번 코드에 추가하지 않으려면,

settings.py의 TEMPLATE_CONTEXT_PROCESSORS에 django.core.context_processors.csrf 가 포함되어 있으면 아래와 같이만 써도 자동으로 csrf 태그가 정보가 추가됨

def show_userinfo3(request):

    return render_to_response('user/input.html', RequestContext(request))



2. form 태그 안에 {% csrf_token %} 추가

<form action="/pasta/user/userinfo4/" method="post"> {% csrf_token %}


이렇게 해서 웹브라우저에서 user/input.html 화면의 소스보기를 보면, {% csrf_token %} 부분에 아래와 같은 코드가 생성됨

<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='c497670310117cb5fbcdc6bc0657d455' /></div>


이런 csrf 정보가 없으면, submit했을 때 서버에서 처리하다가 CSRF token missing or incorrect 에러가 발생함.


AJAX로 처리할 때도 물론 이 token 정보를 보내 줘야 한다.
그러므로, form 전체를 보내는 게 아니라면 반드시 csrfmiddlewaretoken을 포함시켜 보내 줘야 한다.

'Python_Django' 카테고리의 다른 글

Django의 cache 사용  (0) 2012.07.25
decorator 만들기  (0) 2012.07.25
hash(digest) 호출  (0) 2012.07.25
request의 값 처리  (0) 2012.07.25
Django의 session 처리  (0) 2012.07.13
AND


Django는 DB, Filesystem, Cache에 session을 저장할 수 있다.

DB에 session 정보를 저장하도록 설정할 경우, django_session 테이블이 생성된다.


1. session에 값 넣기

   - view 함수에서

     request.session['myname'] = 'michael'


2. session에서 값 얻기

   - view의 함수에서

     myname = request.session['myname']

   

   - Template에서

     {{ request.session.myname }}


'Python_Django' 카테고리의 다른 글

Django의 cache 사용  (0) 2012.07.25
decorator 만들기  (0) 2012.07.25
hash(digest) 호출  (0) 2012.07.25
request의 값 처리  (0) 2012.07.25
CSRF token 생성  (0) 2012.07.25
AND