如何向 Django / React 应用程序添加更改密码功能

How to add change password functionality to Django / React app

我正在尝试向 Django/React 应用程序添加更改密码功能。我正在努力寻找任何方法来完成这项工作。我正在使用 django-rest-auth 和 django-rest-framework。

我很乐意从 React 页面提交密码更改请求,或者将用户重定向到本机 Django 模板驱动的页面 - 离开我的 SPA,但可以让功能正常工作。

但是,更改密码页面需要用户登录,我无法从 React 应用中看到如何执行此操作。我已经使用自定义模板设置了 Django 页面,但是如果我从应用程序 link 到它,那么 URL 重定向到登录:

如果我将请求复制到 cURL 并在终端中 运行 它,我会看到此错误:

# api/urls.py
from django.urls import include, path
from django.contrib.auth import views
from django.conf.urls import include, url

urlpatterns = [
...
    path('password_change/', views.PasswordChangeView.as_view(template_name='account/password_change.html'), name='password_change'),
]

account/password_change.html

{% extends 'account/base.html' %}

{% block body_block %}
  <h1>Change your password</h1>
  <form method="post" action=".">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit" />
  </form>
{% endblock %}

我登录到我的应用程序,然后导航到更改密码页面应该位于的位置:

http://localhost:8000/api/v1/password_change/

然后重定向到:

http://localhost:8000/accounts/login/?next=/api/v1/password_change/

我猜这是因为端点需要身份验证但未提供。但是,尽管我有一个存储的身份验证令牌,但我无法找到如何将其作为网络的一部分发送 link 并且以前使用重置密码的经验表明这不是 Django 从模板中寻找的令牌。

我找了很多年,但找不到任何有关如何向 React 应用程序添加更改密码的示例。这肯定是每个 React 应用程序都需要的东西吧?我缺少什么基本的东西?

编辑:感谢 Rik Schoonbeek 的回答,即 djang-rest-auth 提供的端点可以直接使用。不知何故,我在所有的困惑中都错过了这一点。如果它对其他人有帮助,这里是示例工作代码,它使用 JavaScript 获取和硬编码密码而不是来自表单的数据,只是为了演示该过程。

此代码还演示了检测提取命令中的错误,该命令的工作方式与您预期的不太一样。可能有更好的方法来做到这一点,但这至少给了你一个钩子。

工作代码:

export const changePassword = () => (dispatch) => {
    const token = localStorage.getItem('jwtToken');

    const data = {
        'new_password1': 'othertext',
        'new_password2': 'othertext',
        'old_password': 'sometext'
    };

    var formData  = new FormData();

    // Push our data into our FormData object
    for(var name in data) {
        formData.append(name, data[name]);
    }

    const headers = {
        'Authorization': `Token ${token}`,
    };

    return fetch('/api/v1/rest-auth/password/change/', {
        headers,
        'method': 'POST',
        'body': formData,
    })
        .then(res => {
            if(res.ok) {
                console.log('successfully changed password');
                return res.json();
            } else {
                console.log('error changing password');
            }
        })
        .then(res => {
            console.log('Change password res ', res);
        });
};

而且很重要!将此添加到settings.py,否则无论旧密码是否正确,都会更改密码:

OLD_PASSWORD_FIELD_ENABLED = True

如果您希望用户在重置密码后保持登录状态,也请添加:

LOGOUT_ON_PASSWORD_CHANGE = False

如果您像我一样使用令牌身份验证,则可以通过在请求的 header 中发送令牌来授权用户更改密码。不过,您需要在标记前添加 "Token "(参见下面的示例)。

我就是这样做的,使用 axios 和令牌身份验证。

const response = await axios.post(
  "http://127.0.0.1:8000/rest-auth/password/change/",
  values,
  {
    headers: { Authorization: "Token " + this.props.loginToken }
  }
);

密码更改端点需要发送以下数据:

  • new_password1
  • new_password2
  • old_password

As explained here in the django-rest-auth docs

所以,我上面的 axios 请求中的 "values" 参数是一个包含这些值的 json。