Laravel 10迁移Firebase Auth至PostgreSQL:适配SCRYPT算法方案咨询
Firebase Auth SCRYPT哈希迁移至Laravel 10的可行方案
针对Firebase Auth的SCRYPT哈希无法直接在Laravel 10中验证的问题,以下是两种实用解决方案:
方案一:自定义Laravel哈希驱动(推荐)
通过实现自定义哈希驱动,兼容Firebase的SCRYPT验证逻辑,同时在用户首次登录时自动将密码哈希转换为Laravel默认算法(如Bcrypt/Argon2)。
步骤1:创建自定义哈希类
在app/Hashing/FirebaseScryptHasher.php中编写如下代码:
<?php namespace App\Hashing; use Defuse\Crypto\Core; use Illuminate\Contracts\Hashing\Hasher; use Illuminate\Hashing\AbstractHasher; class FirebaseScryptHasher extends AbstractHasher implements Hasher { protected $signerKey; protected $saltSeparator; protected $rounds; protected $memCost; public function __construct(array $config) { $this->signerKey = base64_decode($config['base64_signer_key']); $this->saltSeparator = base64_decode($config['base64_salt_separator']); $this->rounds = $config['rounds']; $this->memCost = 1 << $config['mem_cost']; // 转换为2^mem_cost的内存成本 } public function make($value, array $options = []) { // 本驱动仅用于验证已有Firebase哈希,不生成新SCRYPT哈希 throw new \RuntimeException('此驱动仅支持验证Firebase SCRYPT哈希,不支持生成新哈希'); } public function check($value, $hashedValue, array $options = []) { // 解码Firebase哈希并拆分salt与哈希值 $decodedHash = base64_decode($hashedValue); $parts = explode($this->saltSeparator, $decodedHash); if (count($parts) !== 2) { return false; } [$salt, $firebaseHash] = $parts; // 使用纯PHP SCRYPT库计算验证哈希 $computedHash = Core::scrypt( $value, $salt, $this->memCost, $this->rounds, 1, strlen($firebaseHash), $this->signerKey ); // 安全比较哈希值 return hash_equals($firebaseHash, $computedHash); } public function needsRehash($hashedValue, array $options = []) { // 强制返回true,提示用户登录时转换为Laravel默认哈希 return true; } }
步骤2:安装纯PHP SCRYPT库
执行Composer命令安装依赖:
composer require defuse/php-scrypt
步骤3:注册自定义哈希驱动
修改app/Providers/AppServiceProvider.php的boot方法:
<?php namespace App\Providers; use App\Hashing\FirebaseScryptHasher; use Illuminate\Support\Facades\Hash; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { Hash::extend('firebase-scrypt', function ($app) { return new FirebaseScryptHasher([ 'base64_signer_key' => env('FIREBASE_SCRYPT_SIGNER_KEY'), 'base64_salt_separator' => env('FIREBASE_SCRYPT_SALT_SEPARATOR'), 'rounds' => env('FIREBASE_SCRYPT_ROUNDS', 8), 'mem_cost' => env('FIREBASE_SCRYPT_MEM_COST', 14), ]); }); } }
步骤4:配置环境变量
在.env文件中添加Firebase的SCRYPT参数:
FIREBASE_SCRYPT_SIGNER_KEY=my_code== FIREBASE_SCRYPT_SALT_SEPARATOR=Bw== FIREBASE_SCRYPT_ROUNDS=8 FIREBASE_SCRYPT_MEM_COST=14
步骤5:登录验证与哈希转换
在用户登录逻辑中,先使用自定义驱动验证Firebase哈希,验证成功后自动转换为Laravel默认哈希并保存:
use Illuminate\Support\Facades\Hash; // 从数据库获取用户的Firebase哈希 $user = User::where('email', $request->email)->first(); if (Hash::driver('firebase-scrypt')->check($request->password, $user->password)) { // 转换为Laravel默认哈希并保存 $user->password = Hash::make($request->password); $user->save(); // 执行用户登录逻辑 auth()->login($user); return redirect('/dashboard'); }
方案二:使用PHP SCRYPT扩展(性能更优)
如果服务器支持安装PHP扩展,可直接使用ext-scrypt替代纯PHP库,提升验证性能:
- 安装扩展(以Ubuntu为例):
sudo apt-get install php-scrypt
- 修改自定义哈希类的
check方法:
public function check($value, $hashedValue, array $options = []) { $decodedHash = base64_decode($hashedValue); $parts = explode($this->saltSeparator, $decodedHash); if (count($parts) !== 2) { return false; } [$salt, $firebaseHash] = $parts; // 使用PHP扩展计算SCRYPT哈希 $computedHash = scrypt( $value, $salt, $this->memCost, $this->rounds, 1, strlen($firebaseHash), $this->signerKey ); return hash_equals($firebaseHash, $computedHash); }
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

