登录后如何修改密码?
How to change password after logging in?
我使用以下代码更改密码,但我得到 "Request failed with status code 400"。谁能告诉我问题出在哪里?
axios.post ('http: // localhost: 1337 / auth / reset-password', {
code: '',
password: '1234567',
passwordConfirmation: '1234567',
}
, {
headers: {
Authorization: `Bearer $ {this.currentUser.jwt}`
}
}
) .then (response => {
// Handle success.
console.log ('Your user \' s password has been changed. ');
})
.catch (error => {
// Handle error.
console.log ('An error occurred:', error);
});
}
提前致谢
您将不得不使用 PUT /users/:id
路由(来自用户 API)
如果您希望用户使用此路由,则必须创建一个 isOwner 策略并将其应用于此路由。
只让当前用户更新自己的密码,而不是所有用户的密码。
这里是一些文档:
另一种替代方法是使用密码重置控制器。该方案是通过 POST
一个密码对象到 http://localhost:1337/password
,控制器将验证当前的 password
然后使用给定的 newPassword
更新密码,并且 return 一个新的jwt token
.
我们将post一个密码对象如下:
{
"identifier": "yohanes",
"password": "123456789",
"newPassword": "123456",
"confirmPassword": "123456"
}
步骤是:
- 创建密码重置路由
/api/password/config/routes.json
:
{
"routes": [
{
"method": "POST",
"path": "/password",
"handler": "password.index"
}
]
}
- 在
/api/password/controllers/password.js
创建密码重置控制器
module.exports = {
index: async ctx => {
return 'Hello World!';
}
}
注意:不要忘记在 Roles -> Permission -> Application
启用 password index
。
将 Postman 指向 http://localhost:1337/password
。响应将显示文本 Hello World!
.
更新密码控制器:
module.exports = {
index: async ctx => {
// Get posted params
// const params = JSON.parse(ctx.request.body); //if post raw object using Postman
const params = ctx.request.body;
// The identifier is required.
if (!params.identifier) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.email.provide',
message: 'Please provide your username or your e-mail.',
})
);
}
// Other params validation
.
.
.
// Get User based on identifier
const user = await strapi.query('user', 'users-permissions').findOne({username: params.identifier});
// Validate given password against user query result password
const validPassword = await strapi.plugins['users-permissions'].services.user.validatePassword(params.password, user.password);
if (!validPassword) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.invalid',
message: 'Identifier or password invalid.',
})
);
} else {
// Generate new hash password
const password = await strapi.plugins['users-permissions'].services.user.hashPassword({password: params.newPassword});
// Update user password
await strapi
.query('user', 'users-permissions')
.update({ id: user.id }, { resetPasswordToken: null, password });
// Return new jwt token
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue({ id: user.id }),
user: sanitizeEntity(user.toJSON ? user.toJSON() : user, { model: strapi.query('user', 'users-permissions').model }),
});
}
}
}
- 密码对象 post 编辑后,控制器将更新用户密码和 return 新创建的 jwt 令牌。
可以找到完整的代码here。在 Strapi v.3.3.2
上测试
这是 yohanes 针对 Strapi v4 的解决方案
出于某种原因,Strapi 团队删除了 users-permission.user 服务的 hashPassword
方法,因此我们现在需要自己生成哈希。为此,我们使用与 v3 相同的 having 方法。我们需要像这样导入 bcrypt:const bcrypt = require("bcryptjs");
新的更改密码需要如下所示:
async changePassword(ctx) {
const userId = ctx.request.body.userId;
const currentPassword = ctx.request.body.currentPassword;
const newPassword = ctx.request.body.newPassword;
if (!userId || !currentPassword || !newPassword) {
return ctx.throw(400, "provide-userId-currentPassword-newPassword");
}
let user = await strapi
.query("plugin::users-permissions.user")
.findOne({ id: userId });
const validPassword = await strapi
.service("plugin::users-permissions.user")
.validatePassword(currentPassword, user.password);
if (!validPassword) {
return ctx.throw(401, "wrong-current-password");
} else {
// Generate new hashed password
const password = bcrypt.hashSync(newPassword, 10);
user = await strapi.query("plugin::users-permissions.user").update({
where: { id: user.id },
data: { resetPasswordToken: null, password },
});
// Return new jwt token
ctx.send({
jwt: strapi.service("plugin::users-permissions.jwt").issue({
id: user.id,
}),
user: sanitizeOutput(user),
});
}
},
我使用以下代码更改密码,但我得到 "Request failed with status code 400"。谁能告诉我问题出在哪里?
axios.post ('http: // localhost: 1337 / auth / reset-password', {
code: '',
password: '1234567',
passwordConfirmation: '1234567',
}
, {
headers: {
Authorization: `Bearer $ {this.currentUser.jwt}`
}
}
) .then (response => {
// Handle success.
console.log ('Your user \' s password has been changed. ');
})
.catch (error => {
// Handle error.
console.log ('An error occurred:', error);
});
}
提前致谢
您将不得不使用 PUT /users/:id
路由(来自用户 API)
如果您希望用户使用此路由,则必须创建一个 isOwner 策略并将其应用于此路由。 只让当前用户更新自己的密码,而不是所有用户的密码。
这里是一些文档:
另一种替代方法是使用密码重置控制器。该方案是通过 POST
一个密码对象到 http://localhost:1337/password
,控制器将验证当前的 password
然后使用给定的 newPassword
更新密码,并且 return 一个新的jwt token
.
我们将post一个密码对象如下:
{
"identifier": "yohanes",
"password": "123456789",
"newPassword": "123456",
"confirmPassword": "123456"
}
步骤是:
- 创建密码重置路由
/api/password/config/routes.json
:
{
"routes": [
{
"method": "POST",
"path": "/password",
"handler": "password.index"
}
]
}
- 在
/api/password/controllers/password.js
创建密码重置控制器
module.exports = {
index: async ctx => {
return 'Hello World!';
}
}
注意:不要忘记在 Roles -> Permission -> Application
启用 password index
。
将 Postman 指向
http://localhost:1337/password
。响应将显示文本Hello World!
.更新密码控制器:
module.exports = {
index: async ctx => {
// Get posted params
// const params = JSON.parse(ctx.request.body); //if post raw object using Postman
const params = ctx.request.body;
// The identifier is required.
if (!params.identifier) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.email.provide',
message: 'Please provide your username or your e-mail.',
})
);
}
// Other params validation
.
.
.
// Get User based on identifier
const user = await strapi.query('user', 'users-permissions').findOne({username: params.identifier});
// Validate given password against user query result password
const validPassword = await strapi.plugins['users-permissions'].services.user.validatePassword(params.password, user.password);
if (!validPassword) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.invalid',
message: 'Identifier or password invalid.',
})
);
} else {
// Generate new hash password
const password = await strapi.plugins['users-permissions'].services.user.hashPassword({password: params.newPassword});
// Update user password
await strapi
.query('user', 'users-permissions')
.update({ id: user.id }, { resetPasswordToken: null, password });
// Return new jwt token
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue({ id: user.id }),
user: sanitizeEntity(user.toJSON ? user.toJSON() : user, { model: strapi.query('user', 'users-permissions').model }),
});
}
}
}
- 密码对象 post 编辑后,控制器将更新用户密码和 return 新创建的 jwt 令牌。
可以找到完整的代码here。在 Strapi v.3.3.2
上测试这是 yohanes 针对 Strapi v4 的解决方案
出于某种原因,Strapi 团队删除了 users-permission.user 服务的 hashPassword
方法,因此我们现在需要自己生成哈希。为此,我们使用与 v3 相同的 having 方法。我们需要像这样导入 bcrypt:const bcrypt = require("bcryptjs");
新的更改密码需要如下所示:
async changePassword(ctx) {
const userId = ctx.request.body.userId;
const currentPassword = ctx.request.body.currentPassword;
const newPassword = ctx.request.body.newPassword;
if (!userId || !currentPassword || !newPassword) {
return ctx.throw(400, "provide-userId-currentPassword-newPassword");
}
let user = await strapi
.query("plugin::users-permissions.user")
.findOne({ id: userId });
const validPassword = await strapi
.service("plugin::users-permissions.user")
.validatePassword(currentPassword, user.password);
if (!validPassword) {
return ctx.throw(401, "wrong-current-password");
} else {
// Generate new hashed password
const password = bcrypt.hashSync(newPassword, 10);
user = await strapi.query("plugin::users-permissions.user").update({
where: { id: user.id },
data: { resetPasswordToken: null, password },
});
// Return new jwt token
ctx.send({
jwt: strapi.service("plugin::users-permissions.jwt").issue({
id: user.id,
}),
user: sanitizeOutput(user),
});
}
},