1. 회원가입 [CREATE]
유저를 create 하는 것이다.
UserCreationForm
- ModelForm을 상속받는다.
- User 모델을 사용한다.
- 첫 번째 인자로 data를 받는다.
- 3개의 필드:
- username
- password1
- password2 (비밀번호 확인)
- django 깃헙
# accounts 앱의 views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login as auth_login
from django.contrib.auth.forms import UserCreationForm
from django.views.decorators.http import require_http_methods
@require_http_methods(['GET', 'POST'])
def signup(request):
if request.user.is_authenticated: # --- 1
return redirect('articles:index')
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
auth_login(request, user) # UserCreationForm은 get_user()가 없음! --- 2
return redirect('articles:index')
else:
form = UserCreationForm()
context = {
'form': form,
}
return render(request, 'accounts/signup.html', context)
is_authenticated
로그인을 한 인증된 사용자라면, articles 앱의 index 로 redirect 되도록 한다.
(즉, 회원가입 기능을 수행할 수 없게 한다.)
(이 속성을 활용하여 base.html에서도 회원가입 버튼을 감출 수 있다.)
auth_login(request, user)
회원가입을 한 후, 자동으로 해당 계정으로 로그인이 되게끔 하는 부분이다.
login 함수의 AuthenticationForm에서는get_user()
메서드를 사용하여 유저 정보를 가져올 수 있었지만, UserCreationForm은 해당 메서드를 지원하지 않는다.
이때,
class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
...
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
UserCreationForm은 save()
메서드를 사용하여 저장할 때 반환하는 객체가 유저 객체이다. 그러므로, 이를 저장하여 auth_login의 인자로 넘겨줄 수 있다.
2. 회원탈퇴 [DELETE]
유저를 delete 하는 것이다.
# accounts의 views.py
from django.shortcuts import redirect
from django.views.decorators.http import require_POST
@require_POST
def delete(request):
if request.user.is_authenticated: # 로그인한 사용자의 경우에만
request.user.delete()
return redirect('articles:index')
- delete()를 사용하여 삭제를 진행한다.
- 유저가 삭제되더라도 세션은 유지된다. 해당 유저의 세션도 함께 지우려면 계정 삭제 코드 이후에
from django.contrib.auth import logout as auth_logout
auth_logout(request)
위의 코드를 작성하면 된다.
- POST 방식만 받기 때문에 delete 함수를 실행하는 버튼은 <form> 태그 에서 POST 방식으로 전달되어야 한다.
3. 회원정보 수정 [UPDATE]
UserChangeForm
사용자의 정보 및 권한을 변경하기 위한 폼이다.
- ModelForm을 상속받는다.
- 첫 번째 인자로 data를 받는다.
- admin 인터페이스에서 사용된다.
- django 깃헙
그러나❗❗❗
일반 사용자 계정 정보를 변경한다고 하기에는 너무 많은 작업이 노출되어있다.
👉 UserChangeForm을 상속받은 새로운 폼을 만들어 활용하는 것이 좋겠다.
# forms.py
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth import get_user_model
User = get_user_model()
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = User
fields = ('email', 'first_name', 'last_name')
UserChangeForm은 User 모델을 모델로 가지는 모델폼이다. 따라서, 우리도 User 모델을 가져와서 특정 필드만 보여질 수 있도록 만들어야 한다. User 모델 확인하며 필드도 확인하기, 공식문서
- django에서 User 모델을 가져올 때는 모델 자체를 import 해서는 안 되고,
get_user_model()
을 통해서만 해야 한다고 권고하고 있다. (미흡하나마 설명을 덧붙이자면, 한 프로젝트 내에 유저가 여러 개 생겼을 때, 유저 모델을 들고오면 코드가 작동하지 않을 수 있기 때문이라고 한다.) 관련 문서 get_user_model()
을 사용하면 현재 활성화된 (currently active) User 모델을 들고온다.
# accounts의 views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.views.decorators.http import require_http_methods
from .forms import CustomUserChangeForm
@login_required
@require_http_methods(['GET', 'POST'])
def update(request):
if request.method =='POST':
form = CustomUserChangeForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
form = CustomUserChangeForm(instance=request.user)
context = {
'form': form,
}
return render(request, 'accounts/update.html', context)
- instance 인자에 request.user을 넣어, 기존 정보가 출력되도록 한다.
이제 위와 같이 제한된 정보가 노출된 형태의 회원정보수정 페이지가 만들어졌다.
4. 비밀번호 변경 [UPDATE]
회원정보 수정 폼에서는 비밀번호를 변경할 수 없다. 비밀번호는 또다른 폼에서 수정해야 한다.
PasswordChangeForm
- 기존 비밀번호를 입력하여 새로운 비밀번호를 설정할 수 있도록 한다.
- SetPasswordForm을 상속받는다.
- 첫 번째 인자로 user가 들어간다. django 깃헙: SetPasswordForm의 __init__ 함수 보기
- (위의 폼은 기존 비밀번호를 입력하지 않고 비밀번호를 설정할 수 있도록 해주는 클래스이다.)
- django 깃헙
회원정보수정 페이지에서,
비밀번호를 변경할 수 있는 폼에 대한 링크를 발견할 수 있는데, 이는 기본적으로 /accounts/password/ 경로로 되어 있다.
그러므로, 해당 url을 사용하여 폼을 만들 수 있다.
# accounts의 views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm
from django.views.decorators.http import require_http_methods
@login_required
@require_http_methods(['GET', 'POST'])
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # --- 1
return redirect('articles:index')
else:
form = PasswordChangeForm(request.user)
context = {
'form': form,
}
return render(request, 'accounts/auth_form.html', context)
update_session_auth_hash(request, user)
- 비밀번호를 변경하면 인증정보가 변경되기 때문에 세션이 무효화되고, 따라서 로그아웃이 된다.
- 즉, 기존 세션과 회원의 인증정보가 일치하지 않게 되므로 세션이 바뀌는 것이다.
- 따라서, 기존 로그인 상태를 유지하려면 기존 세션의 session hash를 업데이트 해주어야 한다.
- 이를 위해 사용되는 게
update_session_auth_hash
이다.- 현재 요청(request)과, 새 session hash가 파생될 업데이트될 사용자 객체를 가져오고, session hash를 적절하게 업데이트 한다.
'웹 > Django' 카테고리의 다른 글
DB (0) | 2022.03.09 |
---|---|
Authentication (1) (0) | 2022.03.09 |
1:N 관계 (0) | 2022.03.09 |
Customizing Authentication (0) | 2022.03.09 |
N:M 관계 (0) | 2022.03.09 |