Django Password Resest Via Email
<p>I'm trying to implement password reset by sending an email to the user with a link which will redirect him/her to a new password form. </p>

<p>I took by example <a href="http://stackoverflow.com/questions/18928144/django-user-registration-password-reset-via-email">this question</a> and <a href="http://ruddra.com/2015/09/18/implementation-of-forgot-reset-password-feature-in-django/" rel="nofollow">this site</a>.</p>

<p>But my problem is a bit different. I don't have a local database containing the users, so I cannot perform operations over their attributes. I receive user data via an API (user id, user email, user password).</p>

<p>So, which is the best way to <strong>generate a unique link</strong> to send via email to user so that this link would <strong>tell me who the user is</strong> and allow me to <strong>reset his/her password</strong>? And also, how could I redirect it in <strong>urls.py</strong>?
I wish that this link could be used only a single time.</p>

<p>My views.py is like this:</p>

<pre><code>def password_reset_form(request):

if request.method == 'GET':
    form = PasswordResetForm()
else:
    form = PasswordResetForm(request.POST) 

    if form.is_valid():
        email = form.cleaned_data['email']

        content_dict = {
            'email': email,
            'domain': temp_data.DOMAIN,
            'site_name': temp_data.SITE_NAME,
            'protocol': temp_data.PROTOCOL,
            }

        subject = content_dict.get('site_name')+ ' - Password Reset'
        content = render_to_string('portal/password_reset_email.html', content_dict)
        send_mail(subject, content, temp_data.FIBRE_CONTACT_EMAIL, [email])

        return render(request, 'portal/password_reset_done.html', {'form': form,})

return render(request, 'portal/password_reset_form.html', {'form': form,})
</code></pre>

<p>And the template the e-mail I'm sending is:</p>

<pre><code>{% autoescape off %}

You're receiving this e-mail because we got a request to reset the password for your user account at {{ site_name }}.

Please go to the following page and choose a new password:

{% block reset_link %}
{{ protocol }}://{{ domain }}/[***some unique link***]
{% endblock %}

If you didn't request a password reset, let us know. 

Thank you.

The {{ site_name }} team.

{% endautoescape %}
</code></pre>

<p>Thanks, guys.</p>

<p>Iâd suggest to borrow the general logic from Django and adapt it to your specific conditions:</p>

<ul>
<li><a href="https://github.com/django/django/blob/master/django/contrib/auth/tokens.py" rel="nofollow"><strong><code>PasswordResetTokenGenerator</code> code</strong></a> â pretty well-documented, very useful</li>
<li><a href="https://docs.djangoproject.com/en/1.10/topics/auth/default/#django.contrib.auth.views.password_reset" rel="nofollow">password reset docs</a> (probably known information, though)</li>
<li><a href="https://github.com/django/django/blob/master/django/contrib/auth/views.py#L378" rel="nofollow">password reset view implementation</a></li>
</ul>

<p>As you can see from <code>PasswordResetTokenGenerator._make_token_with_timestamp()</code>, its algo relies on userâs last login timestamp, so the APIs you consume would need to accommodate that.</p>

<p>You could import the same utility functions used by the aboveâwhere cryptography is concerned itâs better to rely on well-tested solutions. Deep internals are prone to change without a release note though when you update to newer Django versions, so take care.</p>

<p>You could also look into simply storing some carefully randomly generated reset codes along with usernames in your local DB and deleting them when user accesses the reset form, but that is less elegant while being more brittle and infosec-issue prone.</p>

python django django-forms