Reputation: 4120
With django-rest-framework, when you post a reset password (rest-auth/password/reset/), there is an email send to the user email. This email contains a confirmation URL. I would like to change this url because I'm on a REST app case, I want this email to point on my frontend instead of the django backend.
With the confirmation email case, I had to override get_email_confirmation_url
method from the AccountAdapter
. But with the reset password case, I have no clue how to do it (there is no method in the adapter about reseting password).
Any idea?
Upvotes: 5
Views: 2567
Reputation: 79
You can leverage the PASSWORD_RESET_USE_SITES_DOMAIN
setting in your dj_rest_auth configuration.
REST_AUTH = {
"PASSWORD_RESET_USE_SITES_DOMAIN": True,
}
By default, this option is set to False
. However, when set to True
, the password_reset_url
is generated from the Site
model within django.contrib.sites
, fetching the domain
from the SITE_ID
setting defined in your project root settings.
You can create a new Site
object with the domain pointing to your frontend domain. Ensure to set SITE_ID=<your-id>
in your project root settings accordingly.
SITE_ID = 2
Note: Additionally, it's imperative to set SITES_ENABLED = True
. Failure to do so while PASSWORD_RESET_USE_SITES_DOMAIN
is enabled will result in the following error:
ImproperlyConfigured(
"Passing `request=None` requires `sites` to be enabled."
)
To fully utilize dj_rest_auth with minimal customization and relying on its configuration, follow these steps:
<URL>/<uidb64>/<token>/
. You can name the URL whatever you want, but the name argument of the path must be set exactly to "password_reset_confim`. path(
"password/reset/confirm/<uidb64>/<token>/",
PasswordResetConfirmView.as_view(),
name="password_reset_confirm",
)
Here, URL
represents your desired route, typically used by your frontend. The password_reset_confirm in the path is crucial for reversing this URL.
password/reset/confirm
is your URL, your final password_reset_url
will resemble:http://frontend.com/password/reset/confirm/7/uye27829398298/
frontend.com
is site domain fetched from Site
model. It added the protocol all by itself.
With this setup, you are good. You can set these settings in production
environment.
For streamlining this process, consider automating the creation of the site object using a custom app command. Assuming you have an environment variable FRONTEND_URL='http://myfrontend.com'
, you can create a command like so
from django.core.management.base import BaseCommand
from django.contrib.sites.models import Site
from django.conf import settings
from urllib.parse import urlparse
class Command(BaseCommand):
help = "Creates a new site with the specified domain"
def handle(self, *args, **options):
domain = urlparse(settings.FRONTEND_URL).netloc
site, _ = Site.objects.get_or_create(id=settings.SITE_ID)
site.domain = domain
site.name = domain
site.save()
self.stdout.write(self.style.SUCCESS(f'Site "{domain}" created successfully.'))
.netloc
method will get you domain along with. Its good for developemnt if you have port in FRONTEND_URL
. http://localhost:3000
will resolve to localhost:3000
Assuming you created this command in your accounts/management/commands/create_site.py
. Here accounts
is the application name. You can run the following command.
python manage.py create_site
Upvotes: 0
Reputation: 31
I found that If you are using the dj-rest-auth and you want your reset password link to point to the frontend you can use the following setting
In the settings file.
REST_AUTH = {
'PASSWORD_RESET_USE_SITES_DOMAIN': True,
}
Based on https://dj-rest-auth.readthedocs.io/en/latest/configuration.html
Upvotes: 3
Reputation: 4120
I did it with templatetags: https://docs.djangoproject.com/fr/1.10/howto/custom-template-tags/
My templatetags file (e.g. settings_vars.py
):
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def get_settings_var(name):
return getattr(settings, name)
My variable in my settings.py
:
FRONTEND_URL = 'http://localhost:4200/'
ACCOUNT_EMAIL_CONFIRMATION_URL = FRONTEND_URL + 'verify-email/{}'
ACCOUNT_PASSWORD_RESET_CONFIRM = FRONTEND_URL + 'password-reset/confirm/'
Usage in my password_reset_email.html
:
{% load settings_vars %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{% get_settings_var 'ACCOUNT_PASSWORD_RESET_CONFIRM' %}?uidb64={{ uid }}&token={{ token }}
{% endblock %}
If someone know a better solution feel free to comment.
Hope it can helps someone.
Upvotes: 4