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

Laravel中str_random()生成api_token无法保证唯一性问题咨询

问题分析与解决方案

嘿,我懂你遇到的这个坑——这其实是Laravel迁移默认值的一个常见误区!

你在迁移里写的default(str_random(60)),是在执行php artisan migrate命令的瞬间生成了一个固定的随机字符串,然后把这个字符串设为api_token的默认值。也就是说,所有后续创建的用户(包括你种子数据里的两个测试用户)都会复用这个固定值,自然就违反了unique()约束,导致重复问题。

下面给你几个可行的解决办法:

方案一:模型自动生成(推荐,一劳永逸)

这个方法能让所有新创建的用户自动生成唯一的api_token,再也不用手动处理:

打开你的User模型,在boot()方法里添加创建事件监听:

protected static function boot()
{
    parent::boot();

    // 用户创建时自动生成专属api_token
    static::creating(function ($user) {
        $user->api_token = str_random(60);
    });
}

然后修改迁移文件,去掉default(str_random(60))(如果已经运行过原迁移,需要调整表结构):

// 修改后的迁移代码片段
$table->increments('id');
$table->string('name');
$table->string('email');
$table->string('api_token')->unique(); // 移除默认值,由模型自动赋值
$table->string('password');
$table->string('remember_token')->nullable();
// ...其他字段

如果已经运行过原迁移,不想清空数据库的话,可以创建新迁移来修改字段:

php artisan make:migration modify_api_token_in_users_table

新迁移内容如下:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('api_token')->unique()->change();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('api_token')->default(str_random(60))->unique()->change();
    });
}

方案二:种子文件手动生成

如果只是想快速解决当前种子数据的问题,可以直接在种子文件里为每个用户单独生成api_token:

比如你的UsersTableSeeder代码:

public function run()
{
    // 循环创建两个用户,每个都生成独立的api_token
    for ($i = 1; $i <= 2; $i++) {
        \App\User::create([
            'name' => "Test User {$i}",
            'email' => "test{$i}@example.com",
            'password' => bcrypt('your-password'),
            'api_token' => str_random(60), // 每个用户单独生成随机串
        ]);
    }
}

如果用工厂生成用户,记得在工厂定义里设置动态生成:

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => bcrypt('password'),
        'api_token' => str_random(60), // 每次生成实例时都新生成随机串
        'remember_token' => str_random(10),
    ];
});

这样执行db:seed时,每个测试用户的api_token就都是独一无二的了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:54:36