My Profile Photo

DongChanS's blog


수학과 학생의 개발일지


인스타 클론코딩 5, Accounts 앱 (1) - 회원관리

1) Accounts App

1-1. OverView

  1. 회원관리 기능들

    • login_required 데코레이터

    • 로그인

      1. AuthenticationForm
  2. login 함수

  • 회원가입

    1. UserCreationForm
    • 패스워드 수정

      1. PasswordChangeForm

2) 회원관리

2-1. Login_required

유저가 로그인을 하지 않았을 때, 로그인창으로 되돌려주는 기능

django reference 참조

login_required() does the following:

  • If the user isn’t logged in, redirect to settings.LOGIN_URL, passing the current absolute path in the query string. Example: /accounts/login/?next=/polls/3/.
  • If the user is logged in, execute the view normally. The view code is free to assume the user is logged in.

이 함수는 데코레이터로 사용할 수 있으며,

로그인이 되지 않았다면, /accounts/login/?next=/polls/3/와 같은 url로 넘겨주는 기능을 한다.

그러니까, 우리는 이 함수의 기능을 정상적으로 사용하려면 두 가지가 반드시 필요하다.

  1. accounts/login 에서 로그인을 할 것
  2. url의 next 파라미터를 인식하고 원래 어플리케이션의 주소로 넘겨줄 것.

그래서, 회원관리를 위한 어플리케이션은 관례적으로 accounts 앱에서 하는 것이 좋습니다.

2-2. 로그인 기능

from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login as auth_login

def login(request):
    next_path = request.GET.get('next')
    
    if request.method == "POST":
        login_form = AuthenticationForm(request, request.POST)
        if login_form.is_valid():
            auth_login(request, login_form.get_user())
            return redirect(next_path or 'profile',
                            request.user.username)
        else:
            return redirect('accounts:login')
    else:
        login_form = AuthenticationForm()
        return render(request, 'accounts/login.html',{
            'login_form' : login_form
        })

AuthenticationForm으로 로그인을 처리

  • 유효성 검사
  • 검사가 끝난 이후에는 get_user()를 통해 획득한 유저객체를 통하여 로그인시키기.
    • django에서 제공하는 login 함수를 이용

2-3. 회원가입

from django.contrib.auth.forms import UserCreationForm

User 클래스의 ModelForm 대신에 django에서 제공하는 UserCreationForm을 이용하는게 좋습니다.

왜냐하면 일반적으로 회원가입을 할 때 해야하는 유효성 검사(ex, 패스워드 확인, 중복된 아이디 불가, 패스워드 패턴 제한…)들을 자동으로 해주기 때문입니다.

로직은 ModelForm을 사용해서 Post 방식일때 데이터베이스에 저장하고, Get 방식일때 ModelForm을 보여주는 일반적인 방식과 동일하게 작성하면 됩니다.

2-4. 패스워드 수정

from django.contrib.auth.forms import PasswordChangeForm

역시 쟝고에서 제공하는 PasswordChangeForm을 이용하는 것이 좋습니다.

그냥 유저객체 들고와서 password만 바꾸면 되는거 아니냐고 할 수 있겠지만, 패스워드는 해쉬함수로 암호화되서 저장되기 때문에 그것을 직접적으로 바꾸는건 조금 위험합니다.

django reference 를 참고하면,

from django.contrib.auth import update_session_auth_hash

def password_change(request):
    if request.method == 'POST':
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(request, form.user)
    else:
        ...

이런 형식으로 되어있습니다.

일단 유념하셔야 할 것은, PasswordChangeForm에 인자를 집어넣을때는 positional하게 집어넣는 것을 권장하고 있습니다. (user, data)

그리고, update_session_auth_hash라는 함수가 있는데 설명서를 살펴보면,

The default password change views included with Django, PasswordChangeView and the user_change_password view in the django.contrib.auth admin, update the session with the new password hash so that a user changing their own password won’t log themselves out. If you have a custom password change view and wish to have similar behavior, use the update_session_auth_hash() function.

Django에서 제공하고 있는 default password change view는 새로운 패스워드 해쉬에 대해서 세션을 업데이트해서 유저가 패스워드를 바꾸느라 로그아웃을 하지 않아도 된다고 하는데, 우리처럼 custom view funtion을 만든다면, update_session_auth_hash 함수를 통해 동일한 기능을 할 수 있다고 합니다.

….

….

레퍼런스의 말을 들어보니 우리가 view를 만들지 않아도 django에서 자동으로 만들어진 view를 이용할 수 있다는 뉘앙스입니다.

2-5. Django Authenticatio Views

Django reference를 찾아보면,

from django.contrib.auth import views as auth_views

urlpatterns = [
    path('change-password/', auth_views.PasswordChangeView.as_view()),
]

이런식으로 url dispatcher에게 쟝고에서 제공하는 custom view를 제공하도록 하면 일일이 view에서 정의하지 않아도 된다고 합니다.

(다만, 워낙 기본적인 기능들만 있다보니, 디자인적인 부분에서 수정하는게 힘들긴 합니다.)

패스워드 변경 뿐만 아니라 LoginView와 같은 여러 종류의 view들이 있습니다.

comments powered by Disqus