diff --git a/scipost/templates/scipost/login.html b/scipost/templates/scipost/login.html
index 17a677c6bbdfe068c9f471a73a557980a42a9713..93f0070cf817bb934975c42d62a8ae2ef18a5997 100644
--- a/scipost/templates/scipost/login.html
+++ b/scipost/templates/scipost/login.html
@@ -15,7 +15,7 @@
     	<input class="btn btn-primary" type="submit" value="Login" />
       </form>
       <br/>
-      <a href="{% url 'scipost:reset_password' %}">Forgot your password?</a>
+      <a href="{% url 'scipost:password_reset' %}">Forgot your password?</a>
     </div>
 
 
diff --git a/scipost/templates/scipost/reset_password.html b/scipost/templates/scipost/password_reset.html
similarity index 77%
rename from scipost/templates/scipost/reset_password.html
rename to scipost/templates/scipost/password_reset.html
index 48dad3becede7037661443ccf8a70821619269c4..608c44509f901bd779d5966615c7122c5e56103d 100644
--- a/scipost/templates/scipost/reset_password.html
+++ b/scipost/templates/scipost/password_reset.html
@@ -1,6 +1,6 @@
 {% extends 'scipost/base.html' %}
 
-{% block pagetitle %}: Reset Password{% endblock pagetitle %}
+{% block pagetitle %}: Password reset{% endblock pagetitle %}
 
 {% load bootstrap %}
 
@@ -9,7 +9,7 @@
 
 <div class="row justify-content-center">
     <div class="col-md-4">
-          <h2>Reset password request form</h2>
+          <h2>Password reset form</h2>
           <form method="post">
             {% csrf_token %}
             {{ form|bootstrap }}
diff --git a/scipost/templates/scipost/reset_password_confirm.html b/scipost/templates/scipost/password_reset_confirm.html
similarity index 86%
rename from scipost/templates/scipost/reset_password_confirm.html
rename to scipost/templates/scipost/password_reset_confirm.html
index 3ec7dd517c06f04c15e6a16267daa7a58db65a61..589afa0ad82d157eca927490c68ae68e1567ebbe 100644
--- a/scipost/templates/scipost/reset_password_confirm.html
+++ b/scipost/templates/scipost/password_reset_confirm.html
@@ -1,6 +1,6 @@
 {% extends 'scipost/base.html' %}
 
-{% block pagetitle %}: Reset password confirm{% endblock pagetitle %}
+{% block pagetitle %}: Password reset confirmation{% endblock pagetitle %}
 
 {% load bootstrap %}
 
diff --git a/scipost/templates/scipost/password_reset_email.html b/scipost/templates/scipost/password_reset_email.html
new file mode 100644
index 0000000000000000000000000000000000000000..8557330306563bcf5a01b8c704f4b6bee6e00890
--- /dev/null
+++ b/scipost/templates/scipost/password_reset_email.html
@@ -0,0 +1,2 @@
+A password reset token was asked for the account with email {{ email }}. To proceed, please follow the link below:
+{{ protocol}}://{{ domain }}{% url 'scipost:password_reset_confirm' uidb64=uid token=token %}
diff --git a/scipost/templates/scipost/password_reset_subject.txt b/scipost/templates/scipost/password_reset_subject.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9aee39fb7d290d6119dd65f1b6778a22f3546cd1
--- /dev/null
+++ b/scipost/templates/scipost/password_reset_subject.txt
@@ -0,0 +1 @@
+Reset of your SciPost password
diff --git a/scipost/templates/scipost/reset_password_complete.html b/scipost/templates/scipost/reset_password_complete.html
deleted file mode 100644
index 5b8a2148b6d5672e67af8e0913cecd4eeec4811b..0000000000000000000000000000000000000000
--- a/scipost/templates/scipost/reset_password_complete.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends 'scipost/base.html' %}
-
-{% block pagetitle %}: Reset password complete{% endblock pagetitle %}
-
-{% block content %}
-    <p>You have successfully reset your password.</p>
-{% endblock content %}
diff --git a/scipost/templates/scipost/reset_password_email.html b/scipost/templates/scipost/reset_password_email.html
deleted file mode 100644
index cf02eb7a941191e35a2fe2696d94aa38325dc3c0..0000000000000000000000000000000000000000
--- a/scipost/templates/scipost/reset_password_email.html
+++ /dev/null
@@ -1,2 +0,0 @@
-Someone asked for password reset for email {{ email }}. Follow the link below:
-{{ protocol}}://{{ domain }}{% url 'scipost:reset_password_confirm' uidb64=uid token=token %}
diff --git a/scipost/templates/scipost/reset_password_subject.txt b/scipost/templates/scipost/reset_password_subject.txt
deleted file mode 100644
index 5c2ca55e5dfc6bdaf8e07ab4a90d9f524d30876d..0000000000000000000000000000000000000000
--- a/scipost/templates/scipost/reset_password_subject.txt
+++ /dev/null
@@ -1 +0,0 @@
-Reset SciPost password
diff --git a/scipost/urls.py b/scipost/urls.py
index eb671b81acf5b8dbbda8483c3b62e979829889f7..4c157f9ea4f3a9162ead91fd18410854f0426f45 100644
--- a/scipost/urls.py
+++ b/scipost/urls.py
@@ -108,14 +108,37 @@ urlpatterns = [
     url(r'^invitation/(?P<key>.+)$', views.invitation, name='invitation'),
 
     # Authentication
-    # DEPRECauth url(r'^login/$', views.login_view, name='login'),
-    url(r'^login/$', views.SciPostLoginView.as_view(), name='login'),
-    url(r'^logout/$', views.SciPostLogoutView.as_view(), name='logout'),
-    # DEPRECauth url(r'^change_password$', views.change_password, name='change_password'),
-    url(r'^password_change$', views.SciPostPasswordChangeView.as_view(), name='password_change'),
-    url(r'^reset_password_confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
-        views.reset_password_confirm, name='reset_password_confirm'),
-    url(r'^reset_password/$', views.reset_password, name='reset_password'),
+    url(
+        r'^login/$',
+        views.SciPostLoginView.as_view(),
+        name='login'
+    ),
+    url(
+        r'^logout/$',
+        views.SciPostLogoutView.as_view(),
+        name='logout'
+    ),
+    url(
+        r'^password_change$',
+        views.SciPostPasswordChangeView.as_view(),
+        name='password_change'
+    ),
+    url(
+        r'^password_reset/$',
+        views.SciPostPasswordResetView.as_view(),
+        name='password_reset'
+    ),
+    url(
+        r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
+        views.SciPostPasswordResetConfirmView.as_view(),
+        name='password_reset_confirm'
+    ),
+    # DEPRECauth
+    # url(r'^login/$', views.login_view, name='login'),
+    # url(r'^change_password$', views.change_password, name='change_password'),
+    # url(r'^reset_password_confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
+    #     views.reset_password_confirm, name='reset_password_confirm'),
+    # url(r'^reset_password/$', views.reset_password, name='reset_password'),
     url(r'^update_personal_data$', views.update_personal_data, name='update_personal_data'),
 
     # Personal Page
diff --git a/scipost/views.py b/scipost/views.py
index fcba84a7b476c9453d8fc45f0be5363d12bfb4c3..42532a8ea8fb1be3c48c5702e24b19a496bb3e82 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -12,7 +12,9 @@ from django.contrib.auth import login, update_session_auth_hash
 from django.contrib.auth.decorators import login_required
 from django.contrib.auth.models import Group
 from django.contrib.auth.views import password_reset, password_reset_confirm
-from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView
+from django.contrib.auth.views import (
+    LoginView, LogoutView, PasswordChangeView,
+    PasswordResetView, PasswordResetConfirmView)
 from django.core import mail
 from django.core.exceptions import PermissionDenied
 from django.core.mail import EmailMessage, EmailMultiAlternatives
@@ -500,6 +502,63 @@ class SciPostPasswordChangeView(PasswordChangeView):
         return reverse_lazy('scipost:personal_page')
 
 
+class SciPostPasswordResetView(PasswordResetView):
+    """
+    Reset a user's password.
+
+    Derived from django.contrib.auth.views:PasswordResetView.
+
+    Overriden fields:
+    - template_name
+    - email_template_name
+    - subject_template_name
+
+    Overriden methods:
+    - get_success_url
+    """
+
+    template_name = 'scipost/password_reset.html'
+    email_template_name = 'scipost/password_reset_email.html'
+    subject_template_name = 'scipost/password_reset_subject.txt'
+
+    def get_success_url(self):
+        """
+        Add a message confirming the request for a new token, then redirect to homepage.
+        """
+        messages.success(self.request,
+                         ('We have just emailed you a password reset token. '
+                          'Please follow the link in this email to reset your password.'))
+        return reverse_lazy('scipost:index')
+
+
+class SciPostPasswordResetConfirmView(PasswordResetConfirmView):
+    """
+    Confirm reset of password, for all users.
+
+    Derived from django.contrib.auth.views:PasswordResetConfirmView.
+
+    Overriden fields:
+    - template_name
+
+    Overriden methods:
+    - get_success_url
+    """
+    template_name = 'scipost/password_reset_confirm.html'
+
+    def get_success_url(self):
+        """
+        Add a message confirming the reset, then redirect to personal page (for
+        which login will be required).
+
+        For Contributor users, this ends up on the personal page.
+        For organization Contacts, this ends up on the organizations dashboard.
+        """
+        messages.success(self.request, (
+            'Your SciPost password has been reset successfully. '
+            'Please login to see your personal pages.'))
+        return reverse_lazy('scipost:personal_page')
+
+
 @login_required
 @is_contributor_user()
 def mark_unavailable_period(request):
@@ -799,17 +858,18 @@ def personal_page(request, tab='account'):
 #     return render(request, 'scipost/change_password.html', {'form': form})
 
 
-def reset_password_confirm(request, uidb64=None, token=None):
-    return password_reset_confirm(request, template_name='scipost/reset_password_confirm.html',
-                                  uidb64=uidb64, token=token,
-                                  post_reset_redirect=reverse('scipost:login'))
+# DEPRECauth
+# def reset_password_confirm(request, uidb64=None, token=None):
+#     return password_reset_confirm(request, template_name='scipost/reset_password_confirm.html',
+#                                   uidb64=uidb64, token=token,
+#                                   post_reset_redirect=reverse('scipost:login'))
 
 
-def reset_password(request):
-    return password_reset(request, template_name='scipost/reset_password.html',
-                          email_template_name='scipost/reset_password_email.html',
-                          subject_template_name='scipost/reset_password_subject.txt',
-                          post_reset_redirect=reverse('scipost:login'))
+# def reset_password(request):
+#     return password_reset(request, template_name='scipost/reset_password.html',
+#                           email_template_name='scipost/reset_password_email.html',
+#                           subject_template_name='scipost/reset_password_subject.txt',
+#                           post_reset_redirect=reverse('scipost:login'))
 
 
 def _update_personal_data_user_only(request):