오늘은 2023년 11월쯤 Django 오픈소스에 기여하려다가 pull requests를 reject 당한 경험에 대해 말씀드리겠습니다.
설명에 앞서 django에서는 password reset을 해주는 도와주는 CBV가 있습니다.
해당 CBV는 사용자가 비밀번호를 잃어버렸을 경우 이메일로 초기화링크를 보내고, 링크에 접속하면 비밀번호를 초기화 할 수 있는 기능을 제공합니다.
예전에는 '비밀번호 찾기' 기능을 통해 기존 비밀번호를 사용자가 다시 확인하거나 복구할 수 있었고, 이 과정에서는 비밀번호를 비교한 후 변경하는 방식이 주로 사용되었습니다. 이때는 비밀번호를 복호화할 수 있도록 저장하는 경우가 있었죠. 하지만 이는 보안상의 취약점을 남기는 방식이었습니다.
최근에는 보안을 강화하기 위해 비밀번호를 해시로 저장하는 방식이 표준이 되었고, 해시는 단방향 암호화이기 때문에 복호화가 불가능합니다. 이로 인해, 비밀번호를 찾는 대신, 새로운 비밀번호를 생성하게 하는 것이 일반적인 방식으로 자리 잡았습니다.
Django는 후자의 방법을 선택하고 있습니다. 그래서 비밀번호를 재설정을 하려면 초기화를 해야합니다
그 방법을 제공하는게 위에서 말한 CBV입니다
해당 CBV를 사용하기위해서는 아래와 같이 urls.py에 등록만 하면 됩니다.
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
# app_name = 'common'
urlpatterns = [
(... 생략 ...)
path('password_reset/', views.PasswordResetView.as_view(), name='password_reset'),
path('password_reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete')
]
- PasswordResetView : 비밀번호 재설정을 요청하는 폼을 사용자에게 제공하고, 이메일로 비밀번호 재설정 링크를 전송하는 역할을 합니다.
- PasswordResetDoneView : 비밀번호 재설정 이메일이 성공적으로 전송되었다는 확인 메시지를 사용자에게 보여줍니다.
- PasswordResetConfirmView : 이메일로 받은 링크를 통해 접근한 후, 새로운 비밀번호를 설정할 수 있는 폼을 제공합니다.
- PasswordResetCompleteView :비밀번호 재설정이 성공적으로 완료된 후, 완료 메시지를 사용자에게 표시합니다.
위처럼 CBV를 간단하게 사용할 수 있습니다.
근데 해당 CBV의 경우 Django에서 제공하는 app_name = 'common'과 같은 URL 네임스페이스 기능이 에러가 나며 사용할 수 없었습니다.
그래서 저는 왜 그럴까하고 Django 소스코드를 디버깅하며 탐색해보았습니다.
탐색결과 PasswordResetView, PasswordResetForm, template에 문제가 있었습니다.
해결방법
1. password_reset_email.html에서 url인자로 app_name을 받는 것이 아닌 string으로 지정해놓았기 때문입니다.
그래서 아래와 같이 수정하였습니다.
2. forms.py에서 app_name 파라미터를 기본값으로 None으로 설정하고, 만약 입력이 있을 경우 이를 컨텍스트에 포함시켜 템플릿 엔진에 전달합니다. 입력이 없을 때는 특정 문자열을 전달하도록 처리합니다. 이렇게 함으로써 password_reset_email.html에 필요한 인자를 적절히 전달할 수 있게 됩니다.
3. 마지막으로 views.py를 수정해야합니다. dispath함수를 수정하여 URL 네임스페이스를 포함할 수 있게 하였습니다.
form_valid 함수에도 app_name을 추가하여 위에서 정의한 forms.py로 전달할 수 있게 하였습니다.
제가 요청한 PR입니다.
https://github.com/django/django/pull/17508
Add new feature to PasswordResetView, PasswordResetForm and modify associated password_reset_email.html template by taeyoung1005
I'm not fluent in English, and I use a translation tool, so please forgive me for any possible mistranslations. Update PasswordResetView, PasswordResetForm to include new feature in password re...
github.com
제가 작성한 commit 기록 되어있는 링크입니다.
https://github.com/taeyoung1005/django/commit/8e2b69452c1703ca579399fe143740035eab349
Add new feature to PasswordResetView, PasswordResetForm and modify as… · taeyoung1005/django@8e2b694
…sociated password_reset_email.html template Update PasswordResetView, PasswordResetForm to include new feature in password reset logic. Previously, when using the PasswordReset feature, it was no...
github.com
Django forum에도 이 에러에 대해 올라와있습니다. view가 꽤 많고 여러 사람들이 댓글을 달아주셨는데요.
에러의 해결방법보다는 이유만 올려주고 있길래 제가 아래에 추가로 작성하였습니다.
https://forum.djangoproject.com/t/reverse-for-password-reset-confirm-not-found/9788
Reverse for 'password_reset_confirm' not found.
So I’m trying to use the default reset password form from django and this is my urls now: urls: path('reset_password/', auth_views.PasswordResetView.as_view(success_url=reverse_lazy('home:password_reset_done'), template_name="accounts/password_reset.html
forum.djangoproject.com
해결시점 이후로 시간이 지나서, 지금 버전에는 어떤지는 모르겠습니다
다음에 기회가 되면 다시 확인해봐야겠습니다.
읽어주셔서 감사합니다.
'python, 파이썬' 카테고리의 다른 글
Github Action을 이용한 CI/CD (0) | 2024.06.30 |
---|---|
JWT (2) | 2024.04.09 |
Django session 로그인 연장 기능(feat. ajax) (0) | 2023.08.10 |
Django DB 자동 삭제 문제 발견 (0) | 2023.07.18 |