You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ExMachina创建可登录的Phoenix用户账号?

解决Factory创建可登录用户的问题

核心问题

你当前的Factory直接给hashed_password赋值明文字符串,登录时系统用Bcrypt.verify_pass/2验证密码,明文无法匹配哈希值导致失败;同时手动构造结构体跳过了User模块的changeset逻辑,没利用自动哈希密码的机制。另外你设置的密码"password"长度仅8位,不符合User里validate_password要求的最小12位规则。

解决方案

修改Factory,通过User模块的registration_changeset构建用户,让changeset自动处理密码哈希和验证:

defmodule HealthTracker.Factory do
  use ExMachina.Ecto, repo: HealthTracker.Repo

  def user_factory do
    %HealthTracker.Accounts.User{}
    # 调用注册changeset,传入符合规则的邮箱和密码
    |> HealthTracker.Accounts.User.registration_changeset(%{
      email: sequence(:email, &"email-#{&1}@example.com"),
      password: "password123456"  # 长度≥12,满足验证要求
    })
    # 应用changeset得到处理后的用户结构体
    |> Ecto.Changeset.apply_changes()
    # 手动设置已验证状态,确保可直接登录
    |> Map.put(:confirmed_at, NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second))
  end
end

为什么这样有效

  1. 自动哈希密码:registration_changeset会触发maybe_hash_password逻辑,将明文密码用Bcrypt哈希后赋值给hashed_password,同时删除虚拟字段password。
  2. 符合验证规则:changeset自动校验密码长度、邮箱格式等,避免手动构造结构体时出现无效数据。
  3. 模拟已验证状态:手动设置confirmed_at,确保用户处于可登录的已验证状态(如果你的登录逻辑要求邮箱验证)。

验证效果

重新在iex中插入用户:

$ iex -S mix phx.server
iex> Factory.insert(:user)

此时数据库中hashed_password会是Bcrypt生成的合法哈希字符串,使用对应密码即可正常登录。

内容的提问来源于stack exchange,提问作者martins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:40:37