查看源代码 mix phx.gen.auth

mix phx.gen.auth 命令会将一个灵活的、预构建的认证系统生成到您的 Phoenix 应用中。此生成器允许您快速完成将认证添加到代码库的任务,并专注于您的应用程序尝试解决的现实世界问题。

入门

在运行此命令之前,请考虑提交您的工作,因为它会生成多个文件。

让我们从在应用的根目录(或伞形应用中的 apps/my_app_web)中运行以下命令开始:

$ mix phx.gen.auth Accounts User users

An authentication system can be created in two different ways:
- Using Phoenix.LiveView (default)
- Using Phoenix.Controller only

Do you want to create a LiveView based authentication system? [Y/n] Y

认证生成器支持 Phoenix LiveView,以增强用户体验,因此我们将在此处回答 Y。您也可以回答 n 以获取基于控制器的认证系统。

两种方法都会创建一个具有 Accounts.User 架构模块的 Accounts 上下文。最后一个参数是架构模块的复数形式,用于生成数据库表名和路由路径。该 mix phx.gen.auth 生成器类似于 mix phx.gen.html,除了它不接受要添加到架构的附加字段列表,并且它会生成更多上下文函数。

由于此生成器在 mix.exs 中安装了额外的依赖项,因此让我们获取这些依赖项

$ mix deps.get

现在我们需要验证 config/ 中开发和测试环境的数据库连接详细信息,以便迁移器和测试能够正常运行。然后运行以下命令来创建数据库

$ mix ecto.setup

让我们运行测试以确保我们的新认证系统按预期工作。

$ mix test

最后,让我们启动我们的 Phoenix 服务器并尝试一下。

$ mix phx.server

开发人员责任

由于 Phoenix 将此代码生成到您的应用程序中,而不是将这些模块构建到 Phoenix 本身,因此您现在拥有完全的自由来修改认证系统,使其最适合您的用例。使用生成的认证系统的唯一警告是它在生成后不会被更新。因此,随着对 mix phx.gen.auth 输出的改进,您需要确定是否需要将这些更改移植到您的应用程序中。安全相关和其他重要改进将在 CHANGELOG.md 文件和升级说明中明确标记。

生成的代码

以下是有关生成的认证系统的一些说明。

密码哈希

密码哈希机制默认为 Unix 系统的 bcrypt 和 Windows 系统的 pbkdf2。这两个系统都使用 Comeonin 接口

密码哈希机制可以使用 --hashing-lib 选项覆盖。支持以下值

我们建议开发人员考虑使用 argon2,它是所有 3 个中最强大的。缺点是 argon2 对 CPU 和内存非常密集,您将需要更强大的实例来运行您的应用程序。

有关选择这些库的更多信息,请参见 Comeonin 项目

禁止访问

生成的代码附带一个认证模块,该模块包含一些插件,用于获取当前用户、要求认证等。例如,在名为 Demo 的应用程序中,它在该应用程序上运行了 mix phx.gen.auth Accounts User users,您将找到一个名为 DemoWeb.UserAuth 的模块,其中包含诸如

  • fetch_current_user - 如果可用,则获取当前用户信息
  • require_authenticated_user - 必须在 fetch_current_user 之后调用,并要求当前用户存在并已认证
  • redirect_if_user_is_authenticated - 用于少数必须对已认证用户不可用的页面

确认

生成的函数附带一个帐户确认机制,其中用户必须确认其帐户,通常通过电子邮件。但是,生成的代码不会禁止用户在他们的帐户尚未确认的情况下使用应用程序。您可以通过自定义 Auth 模块中的 require_authenticated_user 来添加此功能,以检查 confirmed_at 字段(以及您想要的任何其他属性)。

通知器

生成的代码没有与任何系统集成以发送短信或电子邮件来确认帐户、重置密码等。相反,它只是将一条消息记录到终端。您有责任在生成后与适当的系统集成。

请注意,如果您使用 mix phx.new 生成您的 Phoenix 项目,则您的项目默认配置为使用 Swoosh 邮件器。要在使用 Swoosh 的开发过程中查看通知器电子邮件,请导航到 /dev/mailbox

跟踪会话

所有会话和令牌都将在单独的表中跟踪。这允许您跟踪每个帐户有多少个会话处于活动状态。您甚至可以根据需要将此信息公开给用户。

请注意,每当密码更改(通过重置密码或直接更改)时,所有令牌都会被删除,用户必须在所有设备上重新登录。

用户枚举攻击

用户枚举攻击允许某人检查电子邮件是否在应用程序中注册。生成的认证代码不会尝试防止此类检查。例如,当您注册一个帐户时,如果电子邮件已经注册,代码会通知用户电子邮件已经注册。

如果您的应用程序对枚举攻击很敏感,您需要实现自己的工作流,这些工作流往往与大多数应用程序大不相同,因为您需要仔细平衡安全性和用户体验。

此外,如果您担心枚举攻击,请注意时间攻击。例如,注册新帐户通常需要比帐户已存在时更多的工作(例如写入数据库、发送电子邮件等)。某人可以测量执行这些额外任务所需的时间来枚举电子邮件。这适用于所有可能发送电子邮件、应用内通知等的端点(注册、确认、密码恢复等)。

大小写敏感性

电子邮件查找被设为不区分大小写。不区分大小写的查找是 MySQL 和 MSSQL 中的默认设置。在 SQLite3 中,我们在列定义中使用 COLLATE NOCASE 来支持它。在 PostgreSQL 中,我们使用 citext 扩展

请注意 citext 是 PostgreSQL 本身的一部分,并且在大多数操作系统和包管理器中都与它捆绑在一起。 mix phx.gen.auth 负责创建扩展,在大多数情况下无需额外的操作。如果您的包管理器将 citext 分割成单独的包,您将在迁移时收到错误,您很可能可以通过安装 postgres-contrib 包来解决此问题。

并发测试

如果您使用的是支持并发测试的数据库,则生成的测试将并发运行,这种情况适用于 PostgreSQL。

关于 mix phx.gen.auth 的更多信息

查看 mix phx.gen.auth 以获取更多详细信息,例如使用不同的密码哈希库、自定义 Web 模块命名空间、生成二进制 ID 类型、配置默认选项和使用自定义表名。

其他资源

以下链接包含有关此生成代码的动机和设计的更多信息。