如何为Django / React应用添加更改密码功能

时间:2019-01-05 20:01:51

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

我正在尝试将更改密码功能添加到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'),
]

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/

我的猜测是,这是因为端点需要身份验证并且未提供身份验证。但是,尽管我有一个存储的身份验证令牌,但我无法找到如何将其作为网络链接的一部分发送,并且先前使用重置密码的经验表明,它不是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

1 个答案:

答案 0 :(得分: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
  • old_password

As explained here in the django-rest-auth docs

因此,上述axios请求中的“ values”参数是包含这些值的json。