【问题标题】:How to add change password functionality to Django / React app如何向 Django / React 应用程序添加更改密码功能
【发布时间】:2019-06-01 00:27:05
【问题描述】:

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

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

但是,更改密码页面需要用户登录,我无法从 React 应用程序中看到如何执行此操作。我已经使用自定义模板设置了 Django 页面,但是如果我从应用程序链接到它,那么 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'),
]

帐户/密码更改.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/

我的猜测是,这是因为端点需要身份验证并且没有提供。但是,虽然我有一个存储的身份验证令牌,但我不知道如何将其作为网络链接的一部分发送,并且以前重置密码的经验表明它不是 Django 将从模板中寻找的令牌。

我已经寻找了很长时间,但找不到任何关于如何将更改密码添加到 React 应用程序的示例。这肯定是每个 React 应用程序都需要的东西吗?我缺少什么基本的东西?

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

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

工作代码:

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

【问题讨论】:

  • 你怎么知道允许用户重置特定帐户的密码?您是否向他们的电子邮件帐户发送了一封带有密码重置链接的电子邮件?这是密码过期交易吗?
  • 您好,此功能是供已登录用户在网页中管理其帐户的。它不适用于通过电子邮件链接重置密码。我认为该表单需要常规的基于会话的身份验证,但我通过 django-rest-auth 使用令牌。遗憾的是,django-rest-auth 文档似乎没有提供如何实现密码更改的线索。

标签: django reactjs django-rest-framework django-rest-auth


【解决方案1】:

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

这就是我的做法,使用 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
  • 旧密码

As explained here in the django-rest-auth docs

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

【讨论】:

  • 非常感谢,这行得通!我一直在兜圈子,试图让表单和自定义端点工作。感谢您向我解释,我可以简单地创建自己的 React 表单并将数据发布到现有端点,并在标头中使用登录令牌,就像我在获取用户数据时所做的那样。我一定错过了在重置和更改密码、表单和模板的所有烦恼中尝试这种方法。
  • 是的,将 React 和 DRF 链接在一起对我来说也是一个完整的旅程(仍然认为自己是初学者),但幸运的是我已经修复了整个用户身份验证问题。如果您有更多问题可以在 Facebook 上查找我,我愿意与您一起思考。
  • 谢谢!我遇到了更多问题,但我被卡住了。我确实尝试在 Facebook 上给你发消息,你看到了吗?
猜你喜欢
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 2015-02-09
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
相关资源
最近更新 更多