| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- 'use strict';
- const bcrypt = require('bcryptjs');
- module.exports = app => {
- class Bcrypt extends app.BaseService {
- /**
- * 生成 Bcrypt 加盐哈希(自动生成随机盐)
- * @param {string} plainPassword 明文密码
- * @return {Promise<string>} bcrypt 加密后的哈希字符串
- */
- async generateBcryptHash(plainPassword) {
- try {
- const salt = await bcrypt.genSalt(10); // 纯 JS 异步生成,无阻塞
- // 2. 生成密码哈希(盐值自动拼接在哈希结果中,无需单独存储盐值)
- const hashedPassword = await bcrypt.hash(plainPassword, salt);
- return hashedPassword;
- } catch (error) {
- console.error('Bcrypt 哈希生成失败:', error);
- throw new Error('密码加密失败'); // 生产环境可封装为自定义错误
- }
- }
- /**
- * 验证 Bcrypt 哈希
- * @param {string} plainPassword 明文密码
- * @param {array<string>} storedBcryptHash 数据库存储的哈希字段数组
- * @return {Promise<boolean>} 验证结果
- */
- async verifyBcryptHash(plainPassword, storedBcryptHash = []) {
- if (!Array.isArray(storedBcryptHash) || storedBcryptHash.length === 0) {
- return false;
- }
- for (const hash of storedBcryptHash) {
- if (!hash || typeof hash !== 'string') {
- continue;
- }
- try {
- // 关键:不需要传 ARGON2_OPTIONS,哈希本身包含所有验证所需参数
- const isMatch = await bcrypt.compare(plainPassword, hash);
- if (isMatch) {
- return true;
- }
- } catch (error) {
- console.warn(`单个 Bcrypt 哈希验证出错(哈希值:${hash.substring(0, 20)}...):`, error);
- }
- }
- return false;
- }
- }
- return Bcrypt;
- };
|