必须直接使用 password_hash() 和 password_verify(),禁用手动加盐、双重加密及第三方库;存哈希需 varchar(255);验证用 ===;始终用 password_default;严禁日志泄露哈希值。

直接用 password_hash() 和 password_verify(),别自己封装
Webman 是基于 Workerman 的常驻内存框架,但它的 PHP 运行环境和普通 CLI/FPM 没本质区别——password_hash() 和 password_verify() 完全可用,且是唯一推荐方式。你不需要引入第三方 bcrypt 库(比如 bcrypt npm 包或 phpass),也不该手动拼接 salt 或调用 hash('sha256', ...)。
常见错误现象:
- 在 Webman 中误用 Node.js 风格的
bcrypt.hash(),结果报Class 'bcrypt' not found - 把
password_hash()结果存进数据库时没预留足够长度(VARCHAR(255)是安全下限) - 用
==而非===比较password_verify()返回值,导致类型转换隐患
Webman 中密码哈希必须用 PASSWORD_DEFAULT,别硬写 PASSWORD_BCRYPT
PASSWORD_DEFAULT 会随 PHP 版本自动升级算法(目前是 bcrypt,未来可能是 Argon2i),而 PASSWORD_BCRYPT 锁死在 bcrypt,失去演进能力。Webman 常驻进程不会因 PHP 升级重启,但哈希验证逻辑仍依赖当前 PHP 内置实现,所以必须保持兼容性。
使用场景:
- 新用户注册:直接
password_hash($password, PASSWORD_DEFAULT) - 旧密码迁移:若老系统用的是 MD5,首次登录成功后立即用
password_hash()重哈希并更新数据库 - 验证时无需关心算法细节:
password_verify($input, $storedHash)自动识别并匹配
避免在 Webman 中对密码做额外加密或混淆
有人想“更安全”,在 password_hash() 前对密码加一层 openssl_encrypt() 或拼接固定字符串,这反而破坏 bcrypt 的抗时序攻击设计,还可能引入密钥管理风险。
关键原因:
- bcrypt 已内置随机 salt,每次输出不同,无需外部干预
- 工作因子(cost)由 PHP 内部控制,手动加盐或预处理会让实际强度不可控
- Webman 的常驻内存特性不改变哈希函数行为,但会让错误的“双重加密”逻辑长期驻留,难以清理
示例中错例:$safePassword = openssl_encrypt($password, 'AES-128-CBC', $key, 0, $iv);$hash = password_hash($safePassword, PASSWORD_DEFAULT); —— 不要这样写。
注意 Webman 日志和调试输出可能泄露哈希值
Webman 默认开启调试模式时,var_dump()、Log::debug() 或异常堆栈可能意外打印出完整哈希字符串(如 $2y$10$...)。虽然哈希本身不可逆,但暴露哈希值会增加离线暴力破解机会,尤其当用户使用弱密码时。
实操建议:
- 禁止在日志中记录
$_POST['password']或任何含password字段的完整请求体 - 数据库查询日志开启时,确认 SQL 日志过滤了
INSERT INTO users (pwd)类语句 - 用
password_get_info($hash)替代直接输出哈希值来调试算法信息
最易被忽略的一点:Webman 的 app/exception/Handler.php 若未过滤敏感字段,全局异常捕获可能把哈希连同用户数据一起上报到 Sentry 或日志服务——检查所有异常上下文构造逻辑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











