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

Strapi v4:开发环境启动时代码创建管理员及角色权限

问题描述

项目基于TypeScript开发,为降低新开发者上手门槛,要求开发环境启动时自动预置所有数据,无需手动在Strapi后台录入。目前业务数据(如首页数据)的自动初始化功能可正常运行,但无法通过代码创建管理员账号及对应角色权限。当前采用复制预填充好管理员和角色数据的.db文件实现初始化,但该方式缺乏数据控制权,希望能像创建首页数据一样通过代码完成管理员与角色的初始化。

当前启动函数代码如下:

async bootstrap() {
    try {
      const isFirst = await isFirstRun();

      if (isFirst && process.env.NODE_ENV === 'development') {
        await fs.copyFileSync('./data/data.db', './.tmp/data.db');
        const data = await getHomePage();
        await strapi.services['api::home-page.home-page'].createOrUpdate({
          data,
        });

        console.log(
          '\x1b[32m%s\x1b[0m',
          `Development data copied successfully \nAdmin:${process.env.ADMIN} \npassword: ${process.env.ADMIN_PASS}`,
        );
      }
    } catch (e) {
      console.log(e);
    }
  },
};

此前尝试过Strapi旧版本的管理员创建方案,但不适用于Strapi v4,其他方案也未生效,寻求可行的代码实现方式。

解决方案:Strapi v4 代码实现管理员与角色初始化

Strapi v4的管理员和角色属于内置admin模块,需直接操作对应数据库模型,同时注意密码必须经过加密处理,以下是具体实现步骤:

1. 实现密码加密工具函数

Strapi使用bcrypt加密密码,可直接调用内置依赖实现加密:

import * as bcrypt from 'bcryptjs';

const hashPassword = async (password: string) => {
  const saltRounds = 10;
  return bcrypt.hash(password, saltRounds);
};

2. 创建/获取管理员角色

优先使用Strapi默认的超级管理员角色,若不存在则创建:

const createAdminRole = async () => {
  // 查询默认超级管理员角色
  const role = await strapi.db.query('admin::role').findOne({
    where: { code: 'strapi-super-admin' },
  });

  if (!role) {
    // 若不存在则创建超级管理员角色,并赋予所有权限
    return strapi.db.query('admin::role').create({
      data: {
        name: 'Super Admin',
        code: 'strapi-super-admin',
        description: '拥有全部权限的超级管理员角色',
        permissions: await strapi.db.query('admin::permission').findMany(),
      },
    });
  }
  return role;
};

3. 创建管理员账号

确保角色存在后,创建管理员账号,密码需传入加密后的字符串:

const createAdminUser = async (roleId: number) => {
  const adminEmail = process.env.ADMIN || 'admin@example.com';
  const adminPassword = process.env.ADMIN_PASS || 'Admin123!';

  // 检查管理员是否已存在
  const existingAdmin = await strapi.db.query('admin::user').findOne({
    where: { email: adminEmail },
  });

  if (!existingAdmin) {
    const hashedPassword = await hashPassword(adminPassword);
    return strapi.db.query('admin::user').create({
      data: {
        email: adminEmail,
        password: hashedPassword,
        firstname: 'Admin',
        lastname: 'User',
        roles: [roleId],
        isActive: true,
      },
    });
  }
  return existingAdmin;
};

4. 修改bootstrap函数,替换.db文件复制逻辑

将原有的复制.db文件代码替换为上述初始化逻辑:

async bootstrap() {
    try {
      const isFirst = await isFirstRun();

      if (isFirst && process.env.NODE_ENV === 'development') {
        // 初始化管理员角色
        const adminRole = await createAdminRole();
        // 初始化管理员账号
        await createAdminUser(adminRole.id);
        // 初始化首页数据
        const data = await getHomePage();
        await strapi.services['api::home-page.home-page'].createOrUpdate({
          data,
        });

        console.log(
          '\x1b[32m%s\x1b[0m',
          `开发环境数据初始化成功 \n管理员账号:${process.env.ADMIN || 'admin@example.com'} \n密码: ${process.env.ADMIN_PASS || 'Admin123!'}`,
        );
      }
    } catch (e) {
      console.error('开发环境数据初始化失败:', e);
    }
  },
};

注意事项

  • 确保已安装bcryptjs依赖,未安装可执行:npm install bcryptjs --save-dev
  • 建议在.env文件中配置ADMIN和ADMIN_PASS环境变量,避免硬编码敏感信息
  • isFirstRun()函数需正确判断是否为首次启动(例如检查是否存在管理员账号或标记文件)
  • 该逻辑仅适用于开发环境,生产环境请勿自动创建管理员

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:55:23