我正在尝试将更改密码功能添加到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
答案 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 }
}
);
密码更改端点需要发送以下数据:
As explained here in the django-rest-auth docs
因此,上述axios请求中的“ values”参数是包含这些值的json。