node.js中實(shí)現(xiàn)雙重身份驗(yàn)證機(jī)制的方法詳解
在nodejs中實(shí)現(xiàn)雙重身份驗(yàn)證機(jī)制
雙重身份驗(yàn)證(Two-factor authentication
)是一種安全機(jī)制,它要求用戶提供兩種不同的身份驗(yàn)證因素來訪問他們的帳戶:密碼和發(fā)送到他們的移動設(shè)備的驗(yàn)證碼。在本文中,我們將一步步通過使用speakeasy
在nodejs
中實(shí)現(xiàn)雙重身份驗(yàn)證。
步驟1
首先安裝依賴項(xiàng),我們需要安裝express
和speakeasy
:
npm install express speakeasy
步驟2
創(chuàng)建一個(gè)express
服務(wù),并將其配置使用JSON
中間件和靜態(tài)資源中間件:
const express = require('express'); const app = express(); app.use(express.json()); app.use(express.static('public')); app.listen(3000, () => { console.log('Server started on port 3000'); });
步驟3
創(chuàng)建一個(gè)用戶模型User
,用于在數(shù)據(jù)庫中存儲用戶數(shù)據(jù)。在這個(gè)例子中,我們將使用一個(gè)簡單的數(shù)組來存儲用戶數(shù)據(jù):
const users = []; class User { constructor(id, name, email, password, secret) { this.id = id; this.name = name; this.email = email; this.password = password; this.secret = secret; } } module.exports = { users, User };
步驟4
創(chuàng)建一個(gè)POST
請求的路由用于處理用戶的注冊操作。在此路由中,我們將為用戶生成一個(gè)密鑰并將其保存在數(shù)據(jù)庫中。我們還會向用戶發(fā)送一個(gè)二維碼,用戶可以掃描這些代碼,以便將帳戶添加到他們的應(yīng)用程序中:
const { users, User } = require('./user'); const speakeasy = require('speakeasy'); const QRCode = require('qrcode'); app.post('/register', (req, res) => { const { name, email, password } = req.body; // 為用戶生成新的密鑰 const secret = speakeasy.generateSecret({ length: 20 }); // 保存用戶數(shù)據(jù) const user = new User(users.length + 1, name, email, password, secret.base32); users.push(user); // 生成一個(gè)二維碼供用戶掃描 QRCode.toDataURL(secret.otpauth_url, (err, image_data) => { if (err) { console.error(err); return res.status(500).send('Internal Server Error'); } res.send({ qrCode: image_data }); }); });
步驟5
創(chuàng)建一個(gè)POST
請求的路由用于處理用戶的登錄操作。在此請求中,我們將驗(yàn)證用戶的憑證,并需要從用戶的應(yīng)用程序中獲得驗(yàn)證碼。我們將使用speakeasy
來生成和驗(yàn)證這個(gè)驗(yàn)證碼:
const { users } = require('./user'); const speakeasy = require('speakeasy'); app.post('/login', (req, res) => { const { email, password, token } = req.body; const user = users.find(u => u.email === email); // 驗(yàn)證用戶的憑證 if (!user || user.password !== password) { return res.status(401).send('Invalid credentials'); } // 核實(shí)用戶的令牌 const verified = speakeasy.totp.verify({ secret: user.secret, encoding: 'base32', token, window: 1 }); if (!verified) { return res.status(401).send('Invalid token'); } // 用戶經(jīng)過認(rèn)證 res.send('Login successful'); });
我們通過檢查用戶是否存在以及他們的密碼是否與請求中提供的密碼匹配來驗(yàn)證用戶的憑證。
如果用戶的憑證有效,我們使用speakeasy
來驗(yàn)證二維碼。我們傳遞用戶的密鑰編碼(應(yīng)該是base32
)、請求中提供的令牌和window: 1
(代表令牌在當(dāng)前和前一個(gè)時(shí)間段有效)。
如果令牌無效,我們將返回一個(gè)401未經(jīng)授權(quán)的狀態(tài)碼,其中包含消息"無效令牌"。
如果令牌有效,我們將發(fā)送一個(gè)200OK的狀態(tài)碼,其中包含"成功登錄"的消息。此時(shí),用戶將進(jìn)行身份驗(yàn)證,并可以訪問應(yīng)用程序中受保護(hù)的資源。
步驟6
創(chuàng)建一個(gè)中間件來驗(yàn)證用戶是否已經(jīng)成功登錄。
const speakeasy = require('speakeasy'); exports.requireToken = (req, res, next) => { const { token } = req.body; // Find the user with the given email address const user = users.find(u => u.email === req.user.email); // Verify the user's token const verified = speakeasy.totp.verify({ secret: user.secret, encoding: 'base32', token, window: 1 }); if (!verified) { return res.status(401).send('Invalid token'); } // 令牌有效,繼續(xù)到下一個(gè)中間件或路由處理程序 next(); }
下面這個(gè)路由中添加了requireToken
中間件,需要存在一個(gè)有效的2FA令牌才能繼續(xù)使用:
app.post('/protected', requireToken, (req, res) => { // 只有當(dāng)用戶的令牌有效時(shí)才會調(diào)用此路由處理程序 res.send('Protected resource accessed successfully'); });
總之,雙重身份驗(yàn)證機(jī)制(2FA)是一種強(qiáng)大的安全機(jī)制,它為用戶帳戶增加了額外的保護(hù)層。通過要求用戶提供兩個(gè)不同的身份驗(yàn)證因素,例如密碼和發(fā)送到他們的移動設(shè)備的代碼,2FA可以幫助防止未經(jīng)授權(quán)訪問敏感信息。
以上就是node.js中實(shí)現(xiàn)雙重身份驗(yàn)證機(jī)制的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于node.js雙重身份驗(yàn)證的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
深入理解nodejs搭建靜態(tài)服務(wù)器(實(shí)現(xiàn)命令行)
這篇文章主要介紹了深入理解nodejs搭建靜態(tài)服務(wù)器(實(shí)現(xiàn)命令行),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02Node.js通過配置?strict-ssl=false解決npm安裝卡住問題
使用npm安裝依賴包是常見的任務(wù)之一,有時(shí)會遇到安裝卡住的問題,本文就來介紹一下通過配置?strict-ssl=false解決npm安裝卡住問題,感興趣的可以了解一下2024-12-12node pnpm修改默認(rèn)包的存儲路徑(操作方法)
PNPM是一個(gè)新的包管理工具,也是NPM的另一個(gè)替代方案,與NPM不同,PNPM使用符號鏈接(symlink)而不是復(fù)制文件來安裝包,這篇文章主要介紹了node pnpm修改默認(rèn)包的存儲路徑,需要的朋友可以參考下2024-05-05詳解nodejs微信公眾號開發(fā)——4.自動回復(fù)各種消息
這篇文章主要介紹了詳解nodejs微信公眾號開發(fā)——4.自動回復(fù)各種消息,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04node.js中的events.emitter.removeListener方法使用說明
這篇文章主要介紹了node.js中的events.emitter.removeListener方法使用說明,本文介紹了events.emitter.removeListener的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12webstorm中配置nodejs環(huán)境及npm的實(shí)例
今天小編就為大家分享一篇webstorm中配置nodejs環(huán)境及npm的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05Node.js利用debug模塊打印出調(diào)試日志的方法
debug日志打印模塊主要實(shí)現(xiàn)功能是帶命名空間(模塊名)、時(shí)間戳、色彩輸出日志;將日志寫入文件;瀏覽器端使用;格式化函數(shù);支持自定義方法。下面這篇文章主要介紹了Node.js利用debug模塊打印出調(diào)試日志的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-04-04Node.js用Socket.IO做聊天軟件的實(shí)現(xiàn)示例
本文主要介紹了Node.js用Socket.IO做聊天軟件的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05