登录后如何修改密码?

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"
}

步骤是:

  1. 创建密码重置路由/api/password/config/routes.json:
{
   "routes": [
       {
          "method": "POST",
          "path": "/password",
          "handler": "password.index"
       }
   ]
}
  1. /api/password/controllers/password.js
  2. 创建密码重置控制器
module.exports = {
   index: async ctx => {
       return 'Hello World!';
   }
}

注意:不要忘记在 Roles -> Permission -> Application 启用 password index

  1. 将 Postman 指向 http://localhost:1337/password。响应将显示文本 Hello World!.

  2. 更新密码控制器:

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 }),
          }); 
       }
    }
 }
  1. 密码对象 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),
      });
    }
  },