2020-03-31

Django 15. 본인인증 후 회원탈퇴 구현

Django check_password함수를 통해 비밀번호 인증 후 회원탈퇴를 구현합니다.


1. forms.py 작성

사용자가 회원탈퇴를 시도할 시 본인의 비밀번호를 확인하는 form을 생성하기 위해 forms.py에 아래와 같이 소스를 입력합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# users/forms.py

from django.contrib.auth.hashers import check_password

class CheckPasswordForm(forms.Form):
password = forms.CharField(label='비밀번호', widget=forms.PasswordInput(
attrs={'class': 'form-control',}),
)
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.user = user

def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
confirm_password = self.user.password

if password:
if not check_password(password, confirm_password):
self.add_error('password', '비밀번호가 일치하지 않습니다.')

현재 접속중인 사용자의 password를 가져오기 위해 init 메소드로 user 객체를 생성하고 clean 메소드로 form에 입력된 password 값과 init으로 생성된 현재 사용자의 password 값을 django에서 제공하는 check_password를 통해 비교합니다.

2. views.py 작성

views.py에 아래와 같이 회원탈퇴 view를 입력합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# users/views.py

from .forms import CheckPasswordForm

@login_message_required
def profile_delete_view(request):
if request.method == 'POST':
password_form = CheckPasswordForm(request.user, request.POST)

if password_form.is_valid():
request.user.delete()
logout(request)
messages.success(request, "회원탈퇴가 완료되었습니다.")
return redirect('/users/login/')
else:
password_form = CheckPasswordForm(request.user)

return render(request, 'users/profile_delete.html', {'password_form':password_form})

로그인하지 않은 사용자의 접근을 막기 위해 decorator를 추가하고 form에서 비밀번호 인증을 위한 user객체를 생성하기 위해 request.user로 현재 사용자를 form에 담아 템플릿에 뿌려줍니다. is_valid가 통과되면 delete()로 DB에서 현재 user를 삭제하고 logout()을 통해 세션을 만료시킵니다.

3. urls.py 작성

생성한 회원탈퇴 view를 연결하기 위해 urls.pyurlpatterns에 아래의 path를 추가합니다.

1
2
3
# users/urls.py

path('profile/delete/', views.profile_delete_view, name='profile_delete'),

4. templates.py 작성

templatesusersprofile_delete.html을 생성하고 아래의 소스를 입력합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!-- templates/users/profile_delete.html -->

<form method="POST" novalidate>
{% csrf_token %}
<p><strong>{{ user.user_id }}</strong> 회원님의 계정이 삭제됩니다.<br>탈퇴시 개인정보 및 이용정보가 삭제되며 복구할 수 없습니다. <br>본인의 비밀번호를 입력한 후 하단의 유의사항 동의에 체크하세요.</p>
<div>
<label name="label_password" for="{{ password_form.password.id_for_label }}">{{ password_form.password.label }}</label>
{{ password_form.password }}
{% if password_form.password.errors %}
<script type="text/javascript">
document.getElementsByName('password')[0].setAttribute('class', 'form-control is-invalid')
</script>
{% for error in password_form.password.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% endif %}
<small>
본인인증을 위해 비밀번호를 입력해주세요.
</small>
</div>

<label>
<input type="checkbox" name="ck" onClick="checkDisable(this.form)">
<span>유의사항 동의</span>
</label>

<button type="submit" name="bt" disabled="true" >탈퇴하기</button>
</form>

<script type="text/javascript">
function checkDisable(form) {
if (form.ck.checked == true) {
form.bt.disabled = false;
} else {
form.bt.disabled = true;
}
}
</script>

템플릿에 회원탈퇴시 유의사항과 비밀번호 입력필드를 추가하고 유의사항 동의 Checkbox가 Check되었을때만 탈퇴하기 버튼이 활성회되는 스크립트를 추가합니다.

5. 결과

django-project-15

회원탈퇴 기능을 마지막으로 사용자 앱인 users의 구현은 완료되었습니다. 다음 포스팅부턴 게시판 앱을 생성하고 기본적인 CRUD, 댓글달기, 위지위그 적용, 파일 업로드, 무한 스크롤, 글 추천하기 등을 구현한 개발기록을 포스팅하겠습니다.

*전체 html, css 등은 자세하게 포스팅하지 않습니다. 제 Github에서 소스를 확인하실 수 있습니다.