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