Метод checkpw Comeonin.Bcrypt возвращает false после сброса пароля - Эликсир - PullRequest
0 голосов
/ 31 августа 2018

Я использую 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)

Я проверил БД. Обновленный password_digest правильно сохранен в БД. Не уверен, в чем проблема.

Буду признателен за любую помощь!

1 Ответ

0 голосов
/ 07 сентября 2018

Я решил эту проблему.

Первый уровень расчета HMAC отсутствовал в функции сброса пароля. Я использовал ниже криптографическую хеш-функцию для вычисления того же самого.

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

Теперь все отлично работает!

Спасибо всем, кто откликнулся.

...