【问题标题】:The Comeonin.Bcrypt checkpw method returns false after I Reset Password - ElixirComeonin.Bcrypt checkpw 方法在我重置密码后返回 false - Elixir
【发布时间】:2018-08-31 14:25:42
【问题描述】:

我正在使用 Comeonin.Bcrypt 进行密码加密。注册帐户时工作正常,我可以成功登录。但是,一旦我重置密码,checkpw 方法总是为新密码和旧密码返回 false。我正在使用下面的方法来生成密码哈希。

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)

我已经检查了数据库。更新的密码摘要正确保存在数据库中。不确定是什么问题。

任何帮助将不胜感激!

【问题讨论】:

  • 你在哪里打电话checkpw
  • 我已经添加了登录时调用的方法。
  • argslogin_user/2 来自哪里?您正在将args.session_input.passwordargs_session_input.email 指定的用户的DB password_digest 结果进行比较。 args 里面的数据是否正确?另外,您是否在密码更新到密码创建时执行不同的代码?如果两者使用相同的执行路径,调试起来会更简单。
  • 登录方法的参数如下:%{email: "jeena.rose@mailinator.con", password: "0c30eda324cc9136aeb66ee8170719c3c43640be0868e72eba0bb78383c5c851"} 另外,我使用相同的方法来创建 password_hash在注册和重置密码时。 @AdamMillerchip

标签: elixir hmac password-hash


【解决方案1】:

我已经解决了这个问题。

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

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

现在可以正常使用了!

感谢所有回复的人。

【讨论】:

    猜你喜欢
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    相关资源
    最近更新 更多