장고(Django) 개발: 사용자 관리

웨드   SW 개발/Django  

장고(Django)는 기본적으로 사용자 등록, 로그인(인증), 로그아웃 등 사용자 관리를 위한 모든 객체(django.contrib.auth)와 DB 구성을 제공한다. 공식 위키의 Using the Django authentication system 참고하였다.


/p>

작년에 장고(Django) 프레임워크로 프로젝트를 진행하면서 공부했던 개발 지식을 블로그에 다시 정리하려고 합니다. 개인 위키에 정리했던 것을 옮기는 수준이라, 친절한 설명은 기대하기 어렵고, 프로그래밍 언어와 파이썬 지식이 어느정도 있어야 이해할 수 있을 것입니다.


아래 내용들은 Django 1.6~1.7 버전을 기준으로하고, "쉽고 빠른 웹개발 Django"란 책에서 1/3, 공식 위키에서 1/3, 그리고 나머지는 구글링을 바탕으로 정리한 지식입니다. 말투가 존대와 반말이 섞여있어도 이해바랍니다 :)




1 사용자 관리 구현 방법

2 사용자 관리 Views

3 사용자 로그인

4 사용자 로그아웃

5 사용자 비밀번호 변경

6 사용자 가입




1 사용자 관리 구현 방법

첫째, 장고에서 제공하는 사용자 관리 기능을 그대로 사용하는 방법

  • 보다 간편하게 구현 가능하지만, 세부적 수정이 어려움

둘째, (상속받은) 폼과 프로세스를 커스터마이징 하는 방법

  • 보다 직접적으로 수정가능하지만, 더 많은 코딩이 필요함
  • request.user



2 사용자 관리 Views

참고 : django.contrib.auth.views

views (컨트롤러)
설명
login로그인 처리
logout로그아웃 후 템플릿 출력
logout_then_login로그아웃 후에 다시 로그인 페이지로 이동
password_change비밀번호 변경 폼 출력
password_change_done비밀번호가 정상적으로 변경된 후 출력
password_reset새로운 비밀번호를 이메일로 전달
password_reset_done비밀번호 리셋 후 출력
password_reset_confirm비밀번호를 리셋하는 폼 출력
password_reset_complete비밀번호 리셋 폼에서 정상적으로 리셋된 후 출력
redirect_to_login로그인 페이지로 이동

User 관련 주요 함수

is_authenticated()                              # 로그인 여부
get_full_name()                                 # 사용자 성과 이름 모아서 출력
email.user(subject, message, from_email=None)   # 이메일 보내기
set_password(raw_password)                      # 비밀번호 변경 (알아서 암호화)
check_password(raw_password)                    # 원래 비밀번호와 일치하는지 검사



3 사용자 로그인

장고에서 제공하는 사용자 관리 기능을 그대로 사용하는 첫번째 방법 사용함

URL 지정

django.contrib.auth.views에는 세션과 인증에 관한 다양한 뷰가 존재함

url(r'^login/$''django.contrib.auth.views.login'),    # 로그인 페이지

뷰 코드

django.contrib.auth.views.login에서 기본 제공하는 것이 사용됨

템플릿 코드

/템플릿폴더/registration/login.html

<html>
  <head>
    <title>장고 북마크 - 사용자 로그인</title>
  </head>
  <body>
    <h1>사용자 로그인</h1>
    {% if form.errors %}
      <p>사용자 이름과 비밀번호가 일치하지 않습니다. 다시 시도해보세요.</p>
    {% endif %}
      <form method="post" action=".">{% csrf_token %}
        <p><label for="id_username">사용자 이름:</label>{{ form.username }}</p>
        <p><label for="id_password">비밀번호:</label>{{ form.password }}</p>
        <input type="hidden" name="next" value="/" />
        <input type="submit" value="로그인" />
      </form>
  </body>
</html>



4 사용자 로그아웃

URL 지정

django.contrib.auth.views에는 세션과 인증에 관한 다양한 뷰가 존재함

urlpatterns = patterns('',
    url(r'^logout/$', logout_page),                         # 로그아웃 페이지
)

뷰 코드

from django.http import HttpResponseRedirect
from django.contrib.auth import logout
 
def logout_page(request):
    logout(request)
    return HttpResponseRedirect('/');

템플릿 코드

리다이렉트 되도록 만들었기 때문에 템플릿 없음



5 사용자 비밀번호 변경

비밀번호를 변경하는 폼 페이지와 변경완료 됐을 때 리다이렉트 되는 페이지로 구성됨

장고에서 제공하는 사용자 관리 기능을 그대로 사용하는 첫번째 방법 사용함.

URL 지정

url(r'^password_change/$',
    'django.contrib.auth.views.password_change',
    {'post_change_redirect' '/password_change/done/'}),    # 유저 비밀번호 변경 페이지
(r'^password_change/done/$',
    'django.contrib.auth.views.password_change_done'),       # 유저 비밀번호 변경 완료 페이지

뷰 코드

django.contrib.auth.views.password_change 와 password_change_done 에서 기본 제공하는 것이 사용됨

템플릿 코드

/템플릿폴더/registration/password_change_form.html

{% extends "base.html" %}
{% block title %}사용자 비밀번호 변경{% endblock %}
{% block head %}사용자 비밀번호 변경{% endblock %}
{% block content %}
    {% if form.errors %}
        <p>비밀번호가 잘못 되었습니다. 다시 시도해보세요.</p>
    {% endif %}
    <form method="post" action=".">{% csrf_token %}
        <p>{{ form.old_password.errors }}
        <label for="old_password">기존 비밀번호:</label>{{ form.old_password }}</p>
        <p>{{ form.new_password1.errors }}
        <label for="new_password1">새 비밀번호:</label>{{ form.new_password1 }}</p>
        <p>{{ form.new_password2.errors }}
        <label for="new_password2">새 비밀번호 확인:</label>{{ form.new_password2 }}</p>
        <input type="submit" value="비밀번호 변경" />
    </form>
{% endblock %}

/템플릿폴더/registration/password_change_done.html

{% extends "base.html" %}
{% block title %}사용자 비밀번호 변경 완료{% endblock %}
{% block head %}사용자 비밀번호 변경이 완료되었습니다.{% endblock %}
{% block content %}
    <p>사용자 비밀번호 변경이 완료되었습니다.
        이제 <a href="/login/">로그인</a>하시거나,
        아니면 <a href="/">메인</a>으로 이동할 수 있습니다.</p>
{% endblock %}



6 사용자 가입

(상속받은) 폼과 프로세스를 커스터마이징 하는 두번째 방법을 사용함

URL 지정

url(r'^register/$', register_page),                          # 가입 페이지

forms.py 생성

forms.py는 forms.Form을 상속받아 RegistrationForm 구현

from django import forms
 
class RegistrationForm(forms.Form):
    username = forms.CharField(label='사용자 이름', max_length=30)
    email = forms.EmailField(label='이메일')
    password1 = forms.CharField(label='비밀번호', widget=forms.PasswordInput())
    password2 = forms.CharField(label='비밀번호 확인', widget=forms.PasswordInput())

뷰 코드

from bookmarks.forms import *
 
def register_page(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            user = User.objects.create_user(
                username=form.cleaned_data['username'],
                email=form.cleaned_data['email'],
                password=form.cleaned_data['password1']
            )
            return HttpResponseRedirect('/register/success/')
    else:
        form = RegistrationForm()
             
    variables = RequestContext(request, {
        'form': form
    })
         
    return render_to_response('registration/register.html', variables)

템플릿 코드

폼 객체를 출력하기 위해서 form.as_table, form.as_p, form.as_ul 사용

{% extends "base.html" %}
{% block title %}사용자 가입{% endblock %}
{% block head %}사용자 가입{% endblock %}
{% block content %}
    {% if form.errors %}
        <p>사용자 이름과 비밀번호가 일치하지 않습니다. 다시 시도해보세요.</p>
    {% endif %}
    <form method="post" action=".">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="가입" />
    </form>
{% endblock %}