使用mongoose和bcrypt實現用戶密碼加密

来源:https://www.cnblogs.com/xiaohuochai/archive/2018/02/11/8440272.html
-Advertisement-
Play Games

[1]介紹 [2]用戶模型 [3]加密 [4]驗證 [5]測試 ...


前面的話

  最近在做的個人項目中,需要對密碼進行加密保存,對該操作的詳細步驟記錄如下

 

介紹

  關於mongoose已經寫過博客就不再贅述,下麵主要介紹bcrypt

  bcrypt是一個由兩個外國人根據Blowfish加密演算法所設計的密碼散列函數。實現中bcrypt會使用一個加鹽的流程以防禦彩虹表攻擊,同時bcrypt還是適應性函數,它可以藉由增加迭代之次數來抵禦暴力破解法

  使用npm安裝即可

npm install --save bcrypt

 

用戶模型

  下麵來創建代碼用戶user的schema,用戶名不能重覆

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    bcrypt = require('bcrypt');var UserSchema = new Schema({
    username: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true }
});

module.exports = mongoose.model('User', UserSchema);

 

加密

  下麵加入用戶模型的是Mongoose的中間件,該中間件使用pre前置鉤子,在密碼保存之前,自動地把密碼變成hash。詳細代碼如下

let SALT_WORK_FACTOR = 5
UserSchema.pre('save', function(next) {
    var user = this;

    //產生密碼hash當密碼有更改的時候(或者是新密碼)
    if (!user.isModified('password')) return next();

    // 產生一個salt
    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
        if (err) return next(err);

        //  結合salt產生新的hash
        bcrypt.hash(user.password, salt, function(err, hash) {
            if (err) return next(err);

            // 使用hash覆蓋明文密碼
            user.password = hash;
            next();
        });
    });
});

  在node.bcrypt.js中SALT_WORK_FACTOR預設使用的是10,這裡設置為5

 

驗證

  加密之後,密碼原文被替換為密文了。我們無法解密,只能通過bcrypt的compare方法,對再次傳入的密碼和資料庫中保存的加密後的密碼進行比較,如果匹配,則登錄成功

UserSchema.methods.comparePassword = function(candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};

  把上面的幾個步驟串在一起,完整代碼如下

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    bcrypt = require('bcrypt'),
    SALT_WORK_FACTOR = 5;

var UserSchema = new Schema({
    username: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true }
});

UserSchema.pre('save', function(next) {
    var user = this;

    // only hash the password if it has been modified (or is new)
    if (!user.isModified('password')) return next();

    // generate a salt
    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
        if (err) return next(err);

        // hash the password using our new salt
        bcrypt.hash(user.password, salt, function(err, hash) {
            if (err) return next(err);

            // override the cleartext password with the hashed one
            user.password = hash;
            next();
        });
    });
});

UserSchema.methods.comparePassword = function(candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};

module.exports = mongoose.model('User', UserSchema);

 

測試

  把上面的代碼保存成user-model.js,然後運行下麵代碼來實際測試

var mongoose = require('mongoose'),
    User = require('./user-model');

var connStr = 'mongodb://localhost:27017/mongoose-bcrypt-test';
mongoose.connect(connStr, function(err) {
    if (err) throw err;
    console.log('Successfully connected to MongoDB');
});

// create a user a new user
var testUser = new User({
    username: 'jmar777',
    password: 'Password123'
});

// save user to database
testUser.save(function(err) {
    if (err) throw err;

    // fetch user and test password verification
    User.findOne({ username: 'jmar777' }, function(err, user) {
        if (err) throw err;

        // test a matching password
        user.comparePassword('Password123', function(err, isMatch) {
            if (err) throw err;
            console.log('Password123:', isMatch); // -> Password123: true
        });

        // test a failing password
        user.comparePassword('123Password', function(err, isMatch) {
            if (err) throw err;
            console.log('123Password:', isMatch); // -> 123Password: false
        });
    });
});

  控制臺中輸入如下數據:

  資料庫數據如下:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前Ninject依賴註入是在MVC中使用,最近在WebApi中使用,用之前的MVC方式發現使用介面註入,一直是Null錯誤,網上查詢了一些資源,總結一下,以後備用。 主要分為以下幾步驟: 4、在使用的地方,按照如下調用即可 ...
  • 說到這兩個的差別我們想到的首先就應該是這兩個集合的性質有相對較大的區別,List就像是一個火車,ArrayList就像是自己家的小轎車,List對於裝載的事物有限制一開始必須在泛型定義好的事物,就是拉貨物的火車車廂中都幾乎是貨物, 而小汽車是自家的你想拉啥就拉啥,ArrayList就充當小轎車的角色 ...
  • "回到目錄" 環境 環境,對於開發來說就是部署的一種場景,你可以是調試場景,測試場景,生產場景,當然還可以有很多其它的場景,只要你的項目需要就可以自定義,微軟幫我們定義了三種標準的環境變數,下麵來說一下. 預設定義三種場景 1. Development 開發環境 appsetting.Develop ...
  • 1、Crond定義 crond是Linux系統中用來定期執行命令或指定程式的一種服務或軟體。 (1)linux系統自身定期執行的任務(輪詢系統日誌、備份數據等) (2)用戶執行的任務(定時更新同步時間、網站數據備份等) 2、Crond命令語法 定時任務的命令是crontab,其守護進程是crond( ...
  • NAME vim - Vi IMproved, a programmers text editor #vi的改進,一個程式文本編輯器 1、移動游標的方法 2、查找和替換 /word 向游標下麵尋找一個名為word的字元串,配合n,向下查找,N向上查找 3、刪除、複製和粘貼 dd 刪除游標所在的行 y ...
  • 介紹 Zabbix是一款能夠監控各種網路參數以及伺服器健康性和完整性的軟體。Zabbix使用靈活的通知機制,允許用戶為幾乎任何事件配置基於郵件的告警。這樣可以快速反饋伺服器的問題。基於已存儲的數據,Zabbix提供了出色的報告和數據可視化功能。這些功能使得Zabbix成為容量規劃的理想方案。 新版已 ...
  • Nagios->check_openmanage[Dell R7*] Nagios->check_openmanage[Dell R7*] 2014年11月13日 下午 07:44 2014年11月13日 下午 07:44 需求介紹: 透過Nagios監控Dell R7系列伺服器硬體狀態 環境信息: ...
  • 大概分兩步,先自定義字元串規則如去除空格特殊符號等等,再使用轉義,後面的語句一定要加上單引號。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...