数据库种子数据 封面
Vapor 大型教程

数据库种子数据

当所有写接口都被认证保护后,刚建好的空库却连第一个用户都创建不了。本文教你用 Migration 在初始化时播下一个管理员账号。

为什么需要播种数据

前面我们使用认证中间件,把所有涉及数据修改的 API 都保护了起来,但也带来一个问题。

试想一下我们刚创建数据库,一个用户都还没有,但这时我们需要创建新用户的时候,API 需要我们先以一个合法的用户来登录后才能进行创建用户的操作。现在数据库里没有任何授权用户的信息,所以认证一定会失败,因此也就无法创建新的用户,数据库完全没有办法使用。

这就需要我们在第一次运行创建数据库的时候往里面塞一个合法用户,也就是我们常见到的管理员帐户。

实现 AdminUser 迁移

User.swift 中定义一个遵守 MigrationAdminUser 结构体,在 prepare 里创建并保存管理员:

...
struct AdminUser: Migration {
    typealias Database = PostgreSQLDatabase

    static func prepare(on conn: PostgreSQLConnection) -> Future<Void> {
        let password = try? BCrypt.hash("password")
        guard let hashPassword = password else {
            fatalError("Failed Create Admin User!")
        }

        let user = User(name: "admin", username: "admin", password: hashPassword)
        return user.save(on: conn).transform(to: ())
    }

    static func revert(on conn: PostgreSQLConnection) -> Future<Void> {
        return .done(on: conn)
    }
}

注册迁移

configure.swift 里把它和其他模型一起注册进迁移配置:

...
    var migrations = MigrationConfig()
    migrations.add(model: User.self, database: .psql)
    migrations.add(model: Token.self, database: .psql)
    migrations.add(model: Acronym.self, database: .psql)
    migrations.add(model: Category.self, database: .psql)
    migrations.add(model: AcronymCategoryPivot.self, database: .psql)
    migrations.add(migration: AdminUser.self, database: .psql)
    services.register(migrations)
...
提示:AdminUser 用一个独立的 Migration 而不是某个 Model 的迁移,这样它会在应用首次启动时执行一次,自动往空库里写入一个可用的管理员账号。

本系列其他文章