Prechod z inej TOTP knižnice
Samotné TOTP je prenosné. Balík dodržiava štandardný profil (SHA1, 6 číslic, 30 sekúnd), ktorý používajú autentifikačné aplikácie, takže base32 tajný kľúč vytvorený akoukoľvek knižnicou podľa RFC 6238 generuje ďalej tie isté kódy: používatelia si ponechajú záznamy v aplikácii a 2FA nemusia aktivovať znova. Kompatibilitu dokazujú statické paritné fixtures v repozitári; žiadna externá TOTP knižnica nie je závislosťou balíka.
Samo sa však neprenesie to, ako pôvodná knižnica stĺpce ukladala. Tento balík číta tajný kľúč cez cast encrypted Laravelu (Crypt::encryptString()) a záložné kódy ako JSON zoznam — v režime encrypted šifrovaný rovnako, v režime hashed ako jednosmerné haše. Každý existujúci riadok musí mať tento formát, preto si naplánujte jednorazovú migráciu dát.
Z Laravel Fortify
Fortify používa rovnaké názvy stĺpcov, no ukladá encrypt($secret) a encrypt(json_encode($codes)) — serializované hodnoty. Ak sa prečítajú bez úpravy, tajný kľúč sa vráti ako serializovaný reťazec (každé attempt() potom vyhodí InvalidBase32Exception) a záložné kódy ako prázdny zoznam. Migráciu tohto balíka nepublikujte — stĺpce už existujú. Namiesto toho vymeňte trait TwoFactorAuthenticatable z Fortify za HasTwoFactorAuthentication (pozrite Nastavenie modelu) a raz spustite túto migráciu, s rovnakým APP_KEY:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
// Fortify only adds two_factor_confirmed_at when its `confirm` option is on.
$confirms = Schema::hasColumn('users', 'two_factor_confirmed_at');
Schema::table('users', function (Blueprint $table) use ($confirms): void {
if (! $confirms) {
$table->timestamp('two_factor_confirmed_at')->nullable();
}
$table->unsignedBigInteger('two_factor_last_used_timestep')->nullable();
});
DB::table('users')->whereNotNull('two_factor_secret')->lazyById()->each(
function (object $user) use ($confirms): void {
DB::table('users')->where('id', $user->id)->update([
// Crypt::decrypt() unserializes Fortify's payload; encryptString() is what the cast reads.
'two_factor_secret' => Crypt::encryptString(Crypt::decrypt($user->two_factor_secret)),
'two_factor_recovery_codes' => $user->two_factor_recovery_codes === null
? null
: Crypt::encryptString(Crypt::decrypt($user->two_factor_recovery_codes)),
// Without Fortify's confirmation step, every stored secret was a live second factor.
'two_factor_confirmed_at' => $confirms ? $user->two_factor_confirmed_at : now(),
]);
},
);
}
};Potom zabezpečte, aby sa importované kódy dali porovnať — prichádzajú v čitateľnej podobe, ukladajte ich preto vratne:
// config/two-factor.php
'recovery_codes' => [
'count' => 8,
'storage' => 'encrypted',
],Pri zapnutom potvrdzovaní bol riadok z Fortify s tajným kľúčom, ale bez two_factor_confirmed_at, nedokončenou aktiváciou a aj tu zostane čakajúci. Ak ste voľbu confirm vo Fortify po migrácii vypli, nastavte two_factor_confirmed_at pre tieto riadky sami. Ak neskôr prejdete na predvolený režim hashed, zmeňte nastavenie a nechajte používateľov kódy obnoviť — zmena režimu zneplatní uložené kódy.
Z iných knižníc
Pre každý stĺpec platí rovnaké pravidlo: tajný kľúč musí byť Crypt::encryptString($base32Secret) — hodnotu v čitateľnej podobe zabaľte priamo, hodnotu serializovanú cez encrypt() najprv rozbaľte cez Crypt::decrypt(). Záložné kódy v čitateľnej podobe sa v režime encrypted zmenia na Crypt::encryptString(json_encode($codes)):
use Illuminate\Support\Facades\Crypt;
// The secret column — what the encrypted cast reads:
Crypt::encryptString($base32Secret); // from a plaintext secret
Crypt::encryptString(Crypt::decrypt($storedSecret)); // from an encrypt()-serialized one
// Plaintext recovery codes, under 'storage' => 'encrypted':
Crypt::encryptString(json_encode($codes));Ak pôvodná schéma nemá stĺpec two_factor_last_used_timestep — a two_factor_confirmed_at, nastavený pre každého aktivovaného používateľa — pridajte ich. Stĺpec pre ochranu proti opakovaniu má rovnaký typ, aký vytvára makro:
Schema::table('users', function (Blueprint $table): void {
$table->unsignedBigInteger('two_factor_last_used_timestep')->nullable();
});Iné názvy stĺpcov
Ak sa vaše existujúce stĺpce volajú inak, namiesto premenovania ich premapujte — všetky tabuľky účtov zdieľajú jednu mapu:
// config/two-factor.php — remap for non-standard schemas
'columns' => [
'secret' => 'two_factor_secret',
'recovery_codes' => 'two_factor_recovery_codes',
'confirmed_at' => 'two_factor_confirmed_at',
'last_used_timestep' => 'two_factor_last_used_timestep',
],Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.