구현한 기능
- 비밀번호를 잊어버린 사용자가 비밀번호 초기화 메일 발송

- 받은 메일을 통해 새 비밀번호 설정 페이지(Vue.JS)로 접속
- Django에서 redirect 해주면 uid, token data를 받아서 Vue 동적 라우팅


- 새로운 비밀번호로 변경
문제해결
1. 비밀번호 초기화 메일 발송 실패
urls.py
파일에 비밀번호 초기화를 위한 path를 추가합니다.
path('password/reset/', PasswordResetView.as_view(), name='password_reset'),
그리고 메일을 발송해 보려고 하니 에러가 발생하네요.
django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.
에러 메시지를 보니, `패스워드의 초기화 password_reset`의 사용을 위해서는 password_reset_confirm이라는 name을 가지는 함수의 처리가 필요한 것 같습니다.
따라서 새 패스워드를 입력하는 페이지로 `redirect`하기 위한 path와,
path('password/reset/confirm/uid=<int:uid>&token=<str:token>/', passwordResetRedirect, name='password_reset_redirect'),
새 패스워드를 입력받아 DB에 반영하는 기능을 위한 path를 추가합니다.
path('password/reset/confirm/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
2. NoReverseMatch: 500 Error
이번에는 500 에러가 납니다. 백엔드 코드가 잘못되었네요.
django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' with arguments '('1', 'atspiv-ef80120e759475ff5b718620f8c7c439')' not found. 1 pattern(s) tried: ['account/password/reset/confirm/$']
password_reset_confirm에 잘못된 부분이 있는 것 같습니다. 여기서 좀 헤맸습니다. 그러다가 1 pattern(s) tried: ['account/password/reset/confirm/$']
를 보고 생각했습니다.
리다이렉트를 위해 추가해 둔 path의 name이 잘못 된 것일까? 그럼 name을 바꿔 보자.
3. name 변경
name을 password_reset_confirm으로 바꾸어 줍니다.
# urls.py 변경
path('password/reset/', PasswordResetView.as_view(), name='password_reset'),
path('password/reset/confirm/uid=<int:uid>&token=<str:token>/', views.passwordResetRedirect, name='password_reset_confirm'),
path('password/reset/confirm/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
name이 겹치지만, 한번 이메일 전송을 눌러 보겠습니다.

성공입니다. 비밀번호를 바꾸어 보겠습니다.

잘 변경이 됩니다. 로그인해서 제대로 변경이 되었는지 확인해 보겠습니다.

로그인이 제대로 되네요!
4.최종: 중복된 name을 적절하게 변경
name이 중복된 것이 마음에 들지 않습니다. rest framework에 해당하는 path는 name을 바꾸어 주겠습니다.
# urls.py
path('password/reset/', PasswordResetView.as_view(), name='rest_password_reset'),
path('password/reset/confirm/uid=<int:uid>&token=<str:token>/', passwordResetRedirect, name='password_reset_confirm'),
path('password/reset/confirm/', PasswordResetConfirmView.as_view(), name='rest_password_reset_confirm'),
결론
Django의 RestFramework를 사용하니 직접 구현할 때와 달리 굉장히 편리합니다.
하지만 직접 구현하지 않았기에 에러가 왜 발생하는지 직관적으로 파악하기 어렵다는 것은 라이브러리 사용에 공통되는 아쉬움이네요. 이번 문제의 경우 Docs가 아래와 같이 간단한 파라미터만 나와 있어서 해결하기가 더욱 어려웠습니다.

최근댓글