Password reset link not redirecting to website

喜你入骨 提交于 2019-12-24 00:48:43

问题


I'm trying to implement password reset functionality in my React app with django rest framework. I am using rest_auth.

Issue: Once I tried to reset my password from website, It sends password reset link to email. But on clicking that link it redirects to DRF default password reset page, not to my website's desired password reset page. It is working fine when I tried it from localhost. But once deployed to Heroku it is not working.

Some observations: consider the link below which I received on email

https://mysite.herokuapp.com/password/reset/confirm/MQ/5a1-f42302b192f38cf29a3/

If I forcefully removed trailing slash ( / ) in URL then it redirects to my website password reset page and then it works as expected. I tried removing trailing slash from axios request from React but its not working.

Do I have to configure anything on Heroku?

Here is my React route for password reset page

<Route path='/password/reset/confirm/:uid/:token/' component={PasswordRestConfirm} />

this action below fires upon submitting the form.

export const setNewPassword = (new_password1, new_password2, uid, token) => (dispatch, getState) => {

dispatch({ type: SET_NEW_PASSWORD_START });

var bodyFormData = new FormData();

bodyFormData.append('new_password1', new_password1);
bodyFormData.append('new_password2', new_password2);
bodyFormData.append('uid', uid);
bodyFormData.append('token', token);

axios
    .post(`https://mysite.herokuapp.com/password/reset/confirm/${uid}/${token}/`, bodyFormData)
    .then(res => {
        dispatch(createMessage({ passwordChangeSuccess: 'Your password was set successfully' }));
        dispatch({
            type: SET_NEW_PASSWORD,
            payload: res.data
        });

    })
    .catch(err => {
        dispatch(returnErrors(err.response.data, err.response.status));
        dispatch({
            type: SET_NEW_PASSWORD_FAIL
        });
    });

};

settings.py

ALLOWED_HOSTS = ['mysite.herokuapp.com']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',


    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'corsheaders',
    'rest_auth',
    'rest_auth.registration',
    'rest_framework',
    'rest_framework.authtoken',
    # Some other app


]

SITE_ID = 1

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
}


REST_AUTH_SERIALIZERS = {
    'PASSWORD_RESET_SERIALIZER': 'accounts.api.serializers.PasswordResetSerializer',
    'PASSWORD_RESET_CONFIRM_SERIALIZER ': 'accounts.api.serializers.PasswordResetConfirmSerializer',

}

REST_SESSION_LOGIN = True

CORS_ORIGIN_ALLOW_ALL = True

ACCOUNT_EMAIL_REQUIRED = False

ACCOUNT_EMAIL_VERIFICATION = 'none'

ACCOUNT_UNIQUE_EMAIL = True

ACCOUNT_AUTHENTICATION_METHOD = 'username'



# ***********Email settings **************

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = os.environ['EMAIL_USER']
EMAIL_HOST_PASSWORD = os.environ['EMAIL_PASS']

urls.py

urlpatterns = [
    path('password/reset/confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),

]

view.py

class PasswordResetConfirmView(GenericAPIView):

    serializer_class = PasswordResetConfirmSerializer
    permission_classes = (AllowAny,)

    @sensitive_post_parameters_m
    def dispatch(self, *args, **kwargs):
        return super(PasswordResetConfirmView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(
            {"detail": _("Password has been reset with the new password.")}
        )

serializers.py

class PasswordResetConfirmSerializer(serializers.Serializer):
    """
    Serializer for requesting a password reset e-mail.
    """
    new_password1 = serializers.CharField(max_length=128)
    new_password2 = serializers.CharField(max_length=128)
    uid = serializers.CharField()
    token = serializers.CharField()

    set_password_form_class = SetPasswordForm

    def custom_validation(self, attrs):
        pass

    def validate(self, attrs):
        self._errors = {}

        # Decode the uidb64 to uid to get User object
        try:
            uid = force_text(uid_decoder(attrs['uid']))
            print(uid)
            self.user = UserModel._default_manager.get(pk=uid)
            print(self.user)
        except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
            raise ValidationError({'uid': ['Invalid value']})

        self.custom_validation(attrs)
        # Construct SetPasswordForm instance
        self.set_password_form = self.set_password_form_class(
            user=self.user, data=attrs
        )
        if not self.set_password_form.is_valid():
            raise serializers.ValidationError(self.set_password_form.errors)
        if not default_token_generator.check_token(self.user, attrs['token']):
            raise ValidationError({'token': ['Invalid value']})

        return attrs

    def save(self):
        return self.set_password_form.save()

来源:https://stackoverflow.com/questions/58093916/password-reset-link-not-redirecting-to-website

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!