Laravel怎么加密用户密码_Laravel如何使用Hash加密【详解】

2次阅读

应始终使用 hash::make() 而非 bcrypt() 或 password_hash(),因其自动处理盐值、算法升级、配置驱动及验证兼容性;验证必须用 hash::check(),且需配合 hash::needsrehash() 实现平滑迁移。

Laravel怎么加密用户密码_Laravel如何使用Hash加密【详解】

直接用 Hash::make(),别手写 bcrypt 或调用 bcrypt() 函数 —— laravelHash 门面才是唯一推荐入口,它自动处理盐值、算法升级和验证兼容性。

为什么不能直接用 bcrypt() 函数?

Laravel 的全局 bcrypt() 辅助函数只是对 password_hash() 的简单封装,不走框架的哈希管理机制。这意味着:

  • 无法利用 Hash::needsRehash() 自动识别旧算法(比如从 bcrypt 升级到 argon2)
  • 配置在 config/hashing.php 中的 drivermemory 等参数完全失效
  • 测试时 mock Hash 门面会失败,因为 bcrypt() 是独立函数,不受服务容器控制
  • 密码验证必须配对使用 Hash::check(),而不能混用 password_verify() —— 否则未来切换算法时验证直接崩

Hash::make() 的实际用法和参数控制

它默认读取 config/hashing.php 配置,但允许运行时覆盖。常见场景包括:

  • 注册时加密: $hashed = Hash::make($request->password);
  • 指定 bcrypt 成本因子(仅当 driver=bcrypt):Hash::make($pw, ['rounds' => 14])(Laravel 9+ 支持)
  • 强制使用 argon2id(需 PHP 7.2+ 且编译支持):Hash::driver('argon')->make($pw)
  • 注意:不要传空字符串NULLHash::make(),会返回一个有效但无意义的哈希值,且 Hash::check() 仍可能返回 true

验证密码时必须用 Hash::check(),不是 ==strcmp

哈希值含盐且每次不同,直接比字符串毫无意义。更关键的是:

  • Hash::check() 内部调用 password_verify(),并自动处理算法迁移(例如旧用户还是 bcrypt,新用户已是 argon2,验证仍通)
  • 若手动用 password_verify($input, $user->password),等于绕过 Laravel 的哈希驱动抽象,失去未来升级能力
  • 在模型中做验证?别在 mutator 里调 Hash::make() —— 密码字段应只存哈希值,明文只在控制器/Request 层接触一次

容易被忽略的兼容性细节

生产环境升级 hashing driver 后,老用户不会自动重哈希。必须等他们下次登录,再配合 Hash::needsRehash() 主动更新:

  • 登录逻辑中加判断:if (Hash::needsRehash($user->password)) { $user->password = Hash::make($request->password); $user->save(); }
  • 注意:这个判断只对 Laravel 8.17+ 有效;旧版本即使配置变了,needsRehash() 也始终返回 false
  • 数据库字段长度要够:bcrypt 最长 60 字符,argon2id 默认 97 字符,password 字段至少设为 VARCHAR(255)

哈希不是一劳永逸的事——算法会过时,配置会变,唯一能靠住的,是坚持走 Hash 门面这一条路,其他都是临时补丁。

text=ZqhQzanResources