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
相关产品推荐
相关产品推荐

