www.youtube.com/watch?v=sFPcd6myZrY&list=PL-51WBLyFTg2vW-_6XBoUpE7vpmoR3ztO&index=20
이 포스팅은 다음과 같은 youtube 영상을 따라하면서 배운 내용과 학습 내용을 담은 것이다:
- Dennis Ivy - Password Reset Email | Django Framework (3.0) Crash Course Tutorials (pt 20)
현재 Django Version 3.1.2 를 쓰고 있다. Django는 파이썬을 쓰는 오픈소스 웹 프레임워크이다. 웹사이트 만들때 주로 쓰며, 간단한 것이 큰 특징이다.
(원래는 Introduction to Django Signals / Creating Customer Profiles with Django Signals 가 먼저 해야되는데 약간 다른 Topic이라 생각되어 Password Reset Email 부터 하기로 했다.)
※ urls.py 수정하기
우선, urls.py를 다음과 같이 수정한다:
# urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
...
path('reset_password/', auth_views.PasswordResetView.as_view(), name="reset_password"),
path('pasword_reset_done/', auth_views.PasswordResetDoneView.as_view(), name="password_reset_done"),
path('password_reset_confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name="password_reset_confirm"),
path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(), name="password_reset_complete"),
...
]
첫번째로, from django.contrib.auth import views as auth_views 에서 import views as auth_views 인 이유는, 우리가 기존에 app에 있던 views.py와 혼동을 주지 않기 위해서 다른 이름으로 불러오는 것이다.
두번째로는 password_reset_confirm/<uidb64>/<token>/ 인 부분인데, 이는 Django documentation을 보면 알 수 있다:
Documentation을 보면 <uidb64>와 <token>을 url에 통과를 시켜줘야 한다고 명시되어 있다. <uidb64>의 경우, user id를 암호화 시켜주는 것이고, <token>은 이 아이디와 비밀번호가 일치하는지를 확인시켜주는 것이다.
마지막으로, 이렇게 하고 views.py에 아무것도 추가하지 않아도 된다. 이유는 우리는 애초에 from django.contrib.auth import views as auth_views에서 불러온 함수이기 때문에, 이미 함수는 처리되었기 때문이다. (물론 조금더 customizing을 하고 싶을 경우 우리가 views.py에 새로 코드를 짜주어야 할 것이지만, 이 경우 우리는 Django를 간단하게 배우는데에 초점을 맞추고 있기 때문에 이 단계 까지는 가지 않겠다.)
※ Email SMTP 설정하기
보통 이렇게 비밀번호를 재설정 할 경우에는, 비밀번호를 재설정하기 위해 자신의 이메일 주소로 이메일이 전송되게끔 하고는 한다. 따라서 settings.py에 다음과 같이 설정해준다:
# settings.py
...
# SMTP Configuration
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your_email@example.com'
EMAIL_HOST_PASSWORD = 'your_password'
이 tutorial의 경우, Gmail을 예시로 사용했다. 따라서 EMAIL_HOST는 'smtp.gmail.com'이 되는 것이고, EMAIL_PORT는 587, 587은 TLS 이기 때문에 True 값으로 입력해주게 되는 것이다. 자신이 사용할 이메일과 그 이메일의 비밀번호를 각자 알아서 넣어주면 될 것이다. (이 이메일과 비밀번호는 비밀번호를 재설정하고 싶은 상대에게 이메일을 보내게 해줄 이메일 주소를 입력해야 한다.)
이렇게 하는 방식은 좋으나, production level에서는 이메일 비밀번호와 SECRET_KEY라고 적힌 부분은 따로 json 파일을 만들어서 별도로 보관하여, 사용자들이 접근하지 못하게끔 하는 것이 좋을 것이다:
※ Overriding 기존 template
그렇다면 이제 reset_password에 들어가보자:
하지만 들어가면 이렇게 ugly한 template이 불러와진다. 이럴 경우에는 다음과 같이 urls.py를 바꿔주면 된다:
# urls.py
urlpatterns = [
...
path('reset_password/', auth_views.PasswordResetView.as_view(template_name="accounts/reset_password"), name="reset_password"),
path('pasword_reset_done/', auth_views.PasswordResetDoneView.as_view(template_name="accounts/password_reset_done.html"), name="password_reset_done"),
path('password_reset_confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name="accounts/password_reset_confirm.html"), name="password_reset_confirm"),
path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(template_name="accounts/password_reset_complete.html"), name="password_reset_complete"),
...
]
as_view() 사이에 template_name=""을 추가하고 templates/accounts/에 reset_password.html, password_reset_done.html, password_reset_confirm.html, password_reset_complete.html을 추가해준다. (url의 이름과 template의 이름은 편한대로 바꿔주면 된다.)
reset_password.html은 다음과 비슷해야할 것이다:
<!-- reset_password.html -->
<h3>Password reset</h3>
<p>Forgotten your password? Enter your email address below, and we’ll email instructions for setting a new one.</p>
<form method="post">
{% csrf_token %}
{{form}}
<input type="Submit" name="Send email">
</form>
password_reset_done.html:
<!-- password_reset_done.html -->
<h3>Password reset sent</h3>
<p>We’ve emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.</p>
<p>If you don’t receive an email, please make sure you’ve entered the address you registered with, and check your spam folder.</p>
password_reset_confirm.html:
<!-- password_reset_confirm.html -->
<h3>Enter new password</h3>
<p>Please enter your new password twice so we can verify you typed it in correctly.</p>
<form method="post">
{% csrf_token %}
{{form}}
<input type="Submit" name="Update Password">
</form>
password_reset_complete.html:
<!-- password_reset_complete.html -->
<h3>Password reset complete</h3>
<p>Your password has been set. You may go ahead and log in now.</p>
<a href="/">Log in</a>
reset_password.html 과 password_reset_confirm.html 의 경우, 이메일을 제출하고, 새로운 비밀번호를 제출하는 form이 들어가있기 때문에 위와 같이 form을 넣어줘야 한다.
물론 이렇게 해주어도 다음과 같이 ugly하게 나타난다:
이는 css와 template 수정을 통해 할 수 있을 것이다.
※ 추가로 (password_reset_confirm.html 수정하기)
위에 보여준대로 단순히 {{form}}을 password_reset_confirm.html에 통과시킬 경우, 다음과 같이 화면이 나타난다:
위와 같이 매우 ugly 하게 나타난다. 따라서 이를 조금이나마 원하는대로 바꾸려면 Django Github를 보면서 맞는 field 와 label을 찾아서 하면 된다. 다음을 예시로 본다면:
<!-- password_reset_confirm.html -->
<h3>Enter new password</h3>
<p>Please enter your new password twice so we can verify you typed it in correctly.</p>
<form method="post">
{% csrf_token %}
{{form.new_password1.label}}
{{form.new_password1}}
<br>
{{form.new_password2.label}}
{{form.new_password2}}
<input type="Submit" name="Update Password">
</form>
물론 이렇게 해도 ugly하게 나오는 것은 마찬가지이다. 하지만 Django Github 와 Django Documentation을 적절하게 사용한다면 원하는 방식으로 수정할 수 있을 것이다.
이렇게 비밀번호 재설정하는 것을 이메일을 보내는 것을 통해 구현해냈다. 하지만 아직 이 사용자에 관한 다음 사항들을 설정하지 않았다:
- 아이디를 까먹었을 경우? → 이메일로 아이디를 보내게끔 함
- 비밀번호를 까먹었을 경우? → 아이디와 비밀번호를 입력하고 일치할 경우 새비밀번호/기존 비밀번호를 이메일로 보내줌
이 두가지는 다음 기회가 됐을 때 구현해보도록 하겠다.