회원 가입:
User 객체를 Create 하는 과정
UserCreationForm():
회원 가입시 사용자 입력 데이터를 받는 built-in MdelForm
# accouts/views.py
def signup(request):
if request.method == "POST":
# 회원가입 요청 폼
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
# 회원가입 입력 폼
form = UserCreationForm()
context = {
'form':form
}
return render(request,'accounts/signup.html', context)
⇒ 회원 가입 로직 에러 발생
- 회원가입에 사용하는 UserCreationForm이 기존 유저 모델로 인해 작성된 클래스이기 때문
- ⇒ 대체한 유저 모델로 변경이 필요함
커스텀
# accounts/forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
# 현재 django 프로젝트에 활성화 된 User 객체를 반환하는 함수
model = get_user_model()
get_user_model() : 현재 프로젝트에서 활성화된 사용자 모델 (active user model)을 반환하는 함수
왜 User 모델을 직접 참조하지 않는가? get_user_model()을 사용해 User 모델을 참조하면 커스텀 User 모델을 자동으로 반환해주기 때문 ⇒ Django에서 get_user)model()을 사용해 참조해야 한다고 강조함
def signup(request):
if request.user_is_authenticated:
return redirect('articles:index')
if request.method == "POST":
# 회원가입 요청 폼
form = CustomUserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
# 회원가입 입력 폼
form = CustomUserCreationForm()
context = {
'form':form
}
return render(request,'accounts/signup.html', context)
회원 탈퇴
User 객체를 Delete 하는 과정
urls.py , index.html 에도 추가
# accounts/views.py
def delete(Request):
request.user.delete()
return redirect('articles:index')
유저 정보 Update
User 객체를 Update 하는 과정
UserChangeForm :
회원정보 수정 시 사용자 입력 데이터를 받는 built-in ModelForm
# forms.py
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
# 현재 django 프로젝트에 활성화 된 User 객체를 반환하는 함수
model = get_user_model()
fields = ('first_name','last_name','email') # 출력 필드 재 정의
# views.py
from .forms import CustomUserChangeForm
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)
UserChangeForm 사용 시 문제점
- User 모델의 모든 정보들(fields)까지 모두 출력되어 수정이 가능하기 때문에 일반 사용자들이 접근해서는 안되는 정보는 출력하지 않도록 해야 함
⇒ CustomUserChangeForm에서 접근 가능한 필드를 다시 조정
UserChangeForm 은 관리자 수정폼을 가져오기 때문에, 실제 쓰기 위해서는 조금 더 커스텀이 필요하다.
django user object ⇒ django.contrib.auth 공식문서에서 User model에 대한 필드 명을 알 수 있다.
비밀번호 변경
인증된 사용자의 Session 데이터를 Update 하는 과정
PasswordChangeForm()
비밀번호 변경 시 사용자 입력을 받는 built-in form
# accounts/views.py
from django.contrib.auth.forms import PasswordChangeForm
def change_password(request, user_pk):
if request.method == "POST":
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user)
return redirect('articles:index')
else:
# PasswordChangeForm은 첫번째 인자 user가 필수이다.
form = PasswordChangeForm(request.user)
context = {
'form':form
}
return render(request, 'accounts/change_password.html', context)
비밀번호 변경 페이지 작성
DJANGO는 비밀번호 변경 페이지를 회원정보 수정 FORM에서 별도 주소로 안내
⇒ /user_pk/password/로 보내버림
*****************
# 프로젝트/ urls.py
*****************
form accounts import views
urlpatterns = [
path('<int:user_pk>/password/', views.change_password, name='change_password'),
]
<!-- accounts/change_password.html -->
<form action="{% url 'change_password' user.pk %}" method="POST">
세션 무효화
암호 변경 시 세션 무효화
- 비밀번호가 변경되면 기존 세션과의 회원 인증 정보가 일치하지 않게 되어 버려 로그인 상태가 유지되지 못하고 로그아웃 처리됨
- 비밀번호가 변경되면서 기존 세션과의 회원 인증 정보가 일치하지 않기 때문
update_session_auth_hash(request, user)
암호 변경 시 세션 무효화를 막아주는 함수
⇒ 암호가 변경되면 새로운 password의 Session Data로 기존 session을 자동으로 갱신
# accounts/views.py
from django.contrib.auth import update_session_auth_hash
def change_password(request, user_pk)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user)
return redirect('articles:index')
인증된 사용자에 대한 접근 제한
로그인 사용자에 대해 접근을 제한하는 2가지 방법
- is_authenticated 속성 ( attribute)
- login_required 데코레이터 (decorator)
is_authenticated
사용자가 인증 되었는지 여부를 알 수 있는 User model의 속성 , True / False
모든 User 인스턴스에 대해 항상 True인 읽기 전용 속성, 비인증 사용자(=익명의 사용자)에 대해서는 항상 False
<!-- html -->
<!-- 로그인과 비로그인 상태에서 화면에 출력되는 링크를 다르게 설정하기 -->
{% if request.user.is_authenticated %}
~~~
{% endif %}
# views.py
# 인증된 사용자라면 로그인 / 회원가입 로직을 수행할 수 없도록 하기
def login(request):
if request.user.is_authenticated:
return redirect('articles:index')
if request.method == 'POST':
form = AuthenticationForm(request, request.POST)
if form.is_valid():
auth_login(request, form.get_user())
return redirect('articles:index')
login_required
인증된 사용자에 대해서만 view 함수를 실행시키는 데코레이터
⇒ 비인증 사용자의 경우 /accounts/login/ ( 정해져 있음 ) 주소로 redirect 시킴
# views.py
from django.contrib.auth.decorators import login_required
# 인증된 사용자만 게시글을 작성/수정/삭제 할 수 있도록 수정
@login_required
def create(request):
pass
@login_required
def delete(request, article_pk):
pass
@login_required
def create(update, article_pk):
pass
# 인증된 사용자만 로그아웃/탈퇴/수정/비밀번호 변경 할 수 있도록 수정
@login_required
def logout(request):
pass
# ... delete, update, change_password 등
회원가입 + 로그인
# views.py
# 회원가입 요청 폼
form = CustomUserCreationForm(request.POST)
if form.is_valid():
# form.sava()
user = form.save()
auth_login(request,user) # 회원가입 + 로그인
return redirect('articles:index')
탈퇴 + 기존 사용자 Session Data 삭제
- 사용자 객체 삭제 이후 로그아웃 함수 호출
- 단 탈퇴 → 로그아웃 의 순서를 지켜야함
- 먼저 로그아웃이 진행되면 해당 요청 객체 정보가 없어짐 ⇒ 탈퇴에 필요한 유저 정보 또한 없어짐
# views.py
def delete(request):
request.user.delete()
auth_logout(request)
왜 PasswordChangeForm은 다른 Form과 달리 user 객체를 첫번째 인자로 받을 까?
부모 클래스인 SetPasswordForm의 생성자 함수 구성을 따르기 때문
'TIl' 카테고리의 다른 글
REST API 1 (0) | 2024.04.16 |
---|---|
SQL (1) | 2024.04.16 |
Authentication (0) | 2024.04.16 |
Statics (1) | 2024.04.16 |
Form (0) | 2024.04.16 |