代码之家  ›  专栏  ›  技术社区  ›  Tessy Thomas

这个科莫宁.布里普checkpw方法在我重置密码后返回false-Elixir

  •  0
  • Tessy Thomas  · 技术社区  · 7 年前

    defp put_pass_digest(changeset) do   
        case changeset do
          %Ecto.Changeset{valid?: true, changes: %{password: raw_passwd}} = cs ->
            put_change(cs, :password_digest, hashpwsalt(raw_passwd))
          changeset ->
            changeset
        end
      end
    

    这是更改密码的方法:

    def change_password(conn, %{"user" => %{"code" => code, "password" => password, "repeated_password" => repeated_password}}) do
        token = Repo.one(fetch_valid_token_q(code, "password_reset"))
        changeset = User.change_password_changeset(token.user, %{password: password, repeated_password: repeated_password})
        if changeset.valid? do
          Repo.update(changeset)
          render(conn, "password_changed.html")
        else
          changeset = User.changeset(%User{}, %{})
          conn
          |> put_flash(:info, "Wrong, try again!")
          |> render("reset_password.html", code: code, changeset: changeset)
        end
      end
    

    变更集定义为:

    def change_password_changeset(%User{} = schema, params) do
        schema
        |> changeset(params)
        |> validate_required([:password, :repeated_password])
        |> validate_password()
        |> passwords_match?()
        |> put_pass_digest
      end
    

    下面是登录时调用的方法。

    def login_user(args, _resolution) do
        with {:ok, user}         <- fetch_user_and_verify_password(args.session_input),
             {:ok, jwt, _claims} <- Guardian.encode_and_sign(user, :access)
        do
          {:ok, %{user: user, token: jwt}}
        else
          {:error, :incorrect_login_credentials} ->
            Errors.auth_required
        end
      end
    
    def fetch_user_and_verify_password(params) do
        user = Repo.get_by(User, email: String.downcase(params.email))
    
        if check_password(params.password, user) do
          {:ok, user}
        else
          {:error, :incorrect_login_credentials}
        end
      end
    defp check_password(password, user), do: checkpw(password, user.password_digest)
    

    我查过数据库了。更新后的密码摘要正确保存在数据库中。不知道是什么问题。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Tessy Thomas    6 年前

    我已经解决了这个问题。

    重置密码功能中缺少HMAC计算的第一级。我使用下面的加密哈希函数来计算相同的值。

    def to_hash(ast) do
        :sha256
        |> :crypto.hash(ast)
        |> Base.encode16
      end
    

    现在可以了!

    感谢所有回应的人。