Vue3實(shí)現(xiàn)密碼加密登錄的示例代碼
序言
本文主要內(nèi)容分三部分,第一部分是需求分析,第二部分是實(shí)現(xiàn)步驟,第三部分是問(wèn)題詳解。
如果您只需要解決問(wèn)題,請(qǐng)閱讀第一、二部分即可。
1. 需求分析
在前端,用戶(hù)點(diǎn)擊登錄和注冊(cè)時(shí),在登錄和注冊(cè)接口中不允許看到請(qǐng)求中真正的用戶(hù)密碼。
在后端,用戶(hù)點(diǎn)擊登錄和注冊(cè)時(shí),在數(shù)據(jù)庫(kù)中不允許存取真正的用戶(hù)密碼。


2. 實(shí)現(xiàn)步驟
2.1 實(shí)現(xiàn)前的說(shuō)明
在學(xué)習(xí)如何使用之前,我們要明白的是,在項(xiàng)目中如果進(jìn)行密碼加密,有哪幾種情況。然后就是,實(shí)現(xiàn)密碼加密的方式有哪些,哪一種是相較來(lái)說(shuō),較好用及安全性較高的。
密碼加密實(shí)現(xiàn)情況:
前端進(jìn)行密碼加密,后端也進(jìn)行密碼加密
前端進(jìn)行密碼加密,后端不進(jìn)行密碼加密
前端不進(jìn)行密碼加密,后端進(jìn)行密碼加密
已上這三種情況,在實(shí)際的開(kāi)發(fā)中,使用較多的,當(dāng)然是第一種情況,這種情況可以提供更高的安全性和密碼保護(hù)。
前端將用戶(hù)密碼進(jìn)行加密后再傳輸給后端,可以減少密碼在網(wǎng)絡(luò)傳輸過(guò)程中的風(fēng)險(xiǎn),確保密碼的機(jī)密性。
后端再對(duì)接收到的密碼進(jìn)行加密,將加密后的密碼存儲(chǔ)到數(shù)據(jù)庫(kù)中。這樣即使數(shù)據(jù)庫(kù)遭到非法訪問(wèn),密碼也不會(huì)以明文形式暴露,增加了密碼的安全性。
這一點(diǎn)說(shuō)明到這里打住,不再贅述。
然后就是實(shí)現(xiàn)密碼加密的常用方式:
對(duì)稱(chēng)加密算法:AES、DES、3DES
非對(duì)稱(chēng)加密算法:RSA
哈希函數(shù):MD5、SHA-1、SHA-256、SHA-512
密碼推導(dǎo)函數(shù):BCrypt、PBKDF2、SCrypt
對(duì)稱(chēng)加密算法使用相同密鑰進(jìn)行加密和解密,非對(duì)稱(chēng)加密算法使用公鑰和私鑰,哈希函數(shù)將數(shù)據(jù)轉(zhuǎn)換為固定長(zhǎng)度的哈希值,密碼推導(dǎo)函數(shù)通過(guò)迭代和加鹽增加密碼破解難度。
上述加密方式,從上往下,安全性依次增高。
這一點(diǎn)在這里只做簡(jiǎn)要說(shuō)明,有需要的朋友,請(qǐng)見(jiàn)第三部分對(duì)加密方式的詳細(xì)總結(jié)。
搞清楚這些,然后下面,就是如何使用的問(wèn)題了。
為提高大家的使用效率,這里大澈只提供較常用的情況(第一種),以及較安全的密碼加密方式(BCrypt)的使用。
其它加密方式的使用,與此大同小異。
2.2 編寫(xiě)前端代碼
模板代碼:
<template>
<div>
<input type="text" v-model="username" placeholder="Username" />
<input type="password" v-model="password" placeholder="Password" />
<button @click="register">Register</button>
<button @click="login">Login</button>
</div>
</template
引入依賴(lài):
npm i bcryptjs

邏輯代碼:
<script setup>
// 使用 bcrypt.js 進(jìn)行密碼加密
import bcrypt from 'bcryptjs';
const password = ref('')
// 設(shè)置與后端相同的 cost 鹽值
const cost = 10;
const register = async () => {
// 前端加密密碼
const hashedPassword = await bcrypt.hash(password.value, cost);
// 將用戶(hù)名和加密后的密碼發(fā)送到后端進(jìn)行注冊(cè)
// ...
},
const login = async () => {
// 前端加密密碼
const hashedPassword = await bcrypt.hash(password.value, cost);
// 將用戶(hù)名和加密后的密碼發(fā)送到后端進(jìn)行登錄驗(yàn)證
// ...
}
</script>
2.3 編寫(xiě)后端接口(了解即可)
這里做一下說(shuō)明:
為方便舉例,
cost鹽值這里使用了固定值,但在項(xiàng)目中一般都會(huì)使用隨機(jī)字符串作為鹽值。前端生成鹽值,在登錄和注冊(cè)時(shí)會(huì)和加密的密碼一同傳遞給后端,后端接收后,會(huì)使用對(duì)應(yīng)鹽值對(duì)密碼做二次加密,以及將鹽值存到數(shù)據(jù)庫(kù)中。為方面舉例,后端接口的編寫(xiě)全部都寫(xiě)在了
Controller層,還有一些其他必要的鑒權(quán)驗(yàn)證也都省略了。
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@RestController
public class UserController {
// 設(shè)置與前端相同的 cost 鹽值
private static final int COST = 10;
@Autowired
private PasswordEncoder passwordEncoder;
// 注冊(cè)接口
@PostMapping("/register")
public ResponseEntity<?> registerUser(@RequestBody UserRequest userRequest) {
String username = userRequest.getUsername();
String password = userRequest.getPassword(); // 前端已經(jīng)進(jìn)行了密碼加密
// 后端對(duì)密碼進(jìn)行加密
String encryptedPassword = passwordEncoder.encode(password);
// 存儲(chǔ)用戶(hù)信息及加密后的密碼、對(duì)應(yīng)鹽值到數(shù)據(jù)庫(kù)
// ...
return ResponseEntity.ok("User registered successfully!");
}
// 登錄接口
@PostMapping("/login")
public ResponseEntity<?> loginUser(@RequestBody UserRequest userRequest) {
String username = userRequest.getUsername();
String password = userRequest.getPassword(); // 前端已經(jīng)進(jìn)行了密碼加密
// 從數(shù)據(jù)庫(kù)中根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息
User user = userRepository.findByUsername(username);
if (user == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username or password");
}
// 后端驗(yàn)證密碼
boolean isMatched = passwordEncoder.matches(password, user.getPassword());
// 認(rèn)證成功,生成 JWT Token 等操作
// ...
if (isMatched) {
return ResponseEntity.ok("Login successful!");
} else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username or password");
}
}
}
3. 問(wèn)題詳解
3.1 關(guān)于加密方式的詳細(xì)總結(jié)

AES:
AES是一種對(duì)稱(chēng)加密算法,用于保護(hù)敏感數(shù)據(jù)的機(jī)密性。
它使用相同的密鑰進(jìn)行加密和解密,密鑰長(zhǎng)度可以是128位、192位或256位。
AES是一種高度安全和高效的加密算法,廣泛應(yīng)用于數(shù)據(jù)保護(hù)和傳輸領(lǐng)域。
RSA:
RSA是一種非對(duì)稱(chēng)加密算法,用于加密通信、數(shù)字簽名等安全功能。
RSA使用一對(duì)密鑰,包括公鑰和私鑰。
公鑰用于加密數(shù)據(jù),私鑰用于解密數(shù)據(jù)或生成數(shù)字簽名。
RSA算法基于大數(shù)的因數(shù)分解問(wèn)題,被認(rèn)為是一種安全可靠的加密算法。
MD5:
MD5是一種哈希函數(shù),將輸入數(shù)據(jù)轉(zhuǎn)換為固定長(zhǎng)度的128位哈希值。
MD5是不可逆的,即無(wú)法從哈希值還原出原始數(shù)據(jù)。
MD5常用于校驗(yàn)數(shù)據(jù)完整性,但由于存在碰撞攻擊漏洞,不適合用于密碼加密。
SHA:
SHA是一系列哈希函數(shù),包括SHA-1、SHA-256、SHA-512等。
SHA將輸入數(shù)據(jù)轉(zhuǎn)換為固定長(zhǎng)度的哈希值,用于校驗(yàn)數(shù)據(jù)完整性和密碼存儲(chǔ)等領(lǐng)域。
SHA-1已經(jīng)不再被推薦使用,而SHA-256和SHA-512仍然被廣泛應(yīng)用。
BCrypt:
BCrypt是一種密碼推導(dǎo)函數(shù),用于存儲(chǔ)密碼并提供較高的安全性。
它通過(guò)迭代和加鹽的方式增加密碼破解的難度。
BCrypt使用的鹽值是隨機(jī)生成的,并且每個(gè)密碼都使用獨(dú)特的鹽值進(jìn)行加密。
PBKDF2:
PBKDF2是一種密碼推導(dǎo)函數(shù),通過(guò)迭代和加鹽從密碼中派生出密鑰。
它提供更高的密碼破解難度,適用于密碼存儲(chǔ)和驗(yàn)證場(chǎng)景。
PBKDF2的迭代次數(shù)和鹽值都可以調(diào)整,以增加計(jì)算成本和提高安全性。
SCrypt:
SCrypt是一種密碼推導(dǎo)函數(shù),專(zhuān)門(mén)設(shè)計(jì)來(lái)抵御特定硬件攻擊。
它通過(guò)調(diào)整參數(shù)和內(nèi)存需求增加計(jì)算成本,提高密碼破解的難度。
SCrypt在密碼存儲(chǔ)和驗(yàn)證方面提供更高的安全性,但相對(duì)于其他函數(shù)可能需要更多的計(jì)算資源。
3.2 密碼學(xué)中的不可逆是啥
很枯燥的一段學(xué)術(shù)語(yǔ)言,大家隨便看看即可,哈哈哈。
這里也是為什么使用MD5加密時(shí),常常會(huì)進(jìn)行加鹽處理的原因了。

在密碼學(xué)中,不可逆(irreversible)表示無(wú)法從哈希值還原出原始數(shù)據(jù)。
當(dāng)數(shù)據(jù)經(jīng)過(guò)哈希函數(shù)處理后,生成的哈希值是固定長(zhǎng)度的一串字符。不可逆意味著無(wú)法通過(guò)逆向計(jì)算或解密操作來(lái)獲取原始數(shù)據(jù)。即使輸入數(shù)據(jù)的細(xì)微改變也會(huì)導(dǎo)致生成完全不同的哈希值。
這種不可逆性是哈希函數(shù)的重要特性之一,用于保證數(shù)據(jù)的完整性和驗(yàn)證數(shù)據(jù)的一致性。通過(guò)對(duì)原始數(shù)據(jù)進(jìn)行哈希處理,并將哈希值與預(yù)期的哈希值進(jìn)行比對(duì),可以快速檢查數(shù)據(jù)是否被篡改或損壞。如果哈希值相同,則可以確定數(shù)據(jù)完整性沒(méi)有受到破壞;如果哈希值不同,則說(shuō)明數(shù)據(jù)已被修改,或者數(shù)據(jù)傳輸過(guò)程中出現(xiàn)了錯(cuò)誤。
需要注意的是,雖然哈希函數(shù)是不可逆的,但是存在哈希碰撞的概率,即不同的輸入數(shù)據(jù)可能會(huì)產(chǎn)生相同的哈希值。然而,好的哈希函數(shù)應(yīng)該具有極低的碰撞概率,以確保數(shù)據(jù)完整性和安全性。
3.3 Base64是加密方式嗎
Base64編碼只是一種編碼傳輸方式,不是加密算法。
它將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為可打印的ASCII字符,常用于在文本協(xié)議中傳輸或存儲(chǔ)二進(jìn)制數(shù)據(jù),例如在電子郵件中傳輸附件、在網(wǎng)頁(yè)中嵌入圖像等。
我們常常會(huì)將Base64誤解為它是一種加密方式,其實(shí)不然,Base64和我們常用的JWT一樣,都是一種數(shù)據(jù)編碼傳輸方式,只不過(guò)Base64常用于在文本環(huán)境中傳輸圖片、文件。
以下是常用應(yīng)用場(chǎng)景的詳細(xì)說(shuō)明:
在文本環(huán)境傳輸二進(jìn)制數(shù)據(jù):由于某些文本協(xié)議或傳輸機(jī)制只支持文本數(shù)據(jù),無(wú)法直接傳輸二進(jìn)制數(shù)據(jù)。在這種情況下,可以使用Base64編碼將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為文本格式,以便在文本環(huán)境中傳輸,例如在電子郵件中嵌入圖片或在XML、JSON等格式中傳遞二進(jìn)制數(shù)據(jù)。數(shù)據(jù)存儲(chǔ):某些存儲(chǔ)系統(tǒng)或數(shù)據(jù)庫(kù)可能只接受文本數(shù)據(jù),無(wú)法直接存儲(chǔ)二進(jìn)制數(shù)據(jù)。為了在這些系統(tǒng)中存儲(chǔ)二進(jìn)制數(shù)據(jù),可以使用Base64編碼將其轉(zhuǎn)換為文本格式,然后存儲(chǔ)為文本字段。URL傳遞:某些特定的URL傳遞場(chǎng)景中,特殊字符如"+"、"/"等會(huì)被轉(zhuǎn)義或造成問(wèn)題。為了避免這些問(wèn)題,可以使用Base64編碼將數(shù)據(jù)轉(zhuǎn)換為URL安全的字符集,以便在URL中傳遞。
雖然Base64有以上作用,但它會(huì)導(dǎo)致數(shù)據(jù)膨脹,增加數(shù)據(jù)的大小。
在傳輸大量二進(jìn)制數(shù)據(jù)或?qū)鬏斝视休^高要求的情況下,如傳輸大視頻、大圖片、大文件等,不易使用。
如果需要在文本環(huán)境中傳輸大文件,可以考慮使用其他更合適的技術(shù),例如使用壓縮算法對(duì)文件進(jìn)行壓縮,或者使用分布式文件系統(tǒng)或云存儲(chǔ)服務(wù),如Minio、OSS,來(lái)處理大文件的傳輸和存儲(chǔ)。
結(jié)語(yǔ)
到此這篇關(guān)于Vue3實(shí)現(xiàn)密碼加密登錄的示例代碼的文章就介紹到這了,更多相關(guān)Vue3 密碼加密登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中使用echarts以及簡(jiǎn)單關(guān)系圖的點(diǎn)擊事件方式
這篇文章主要介紹了vue中使用echarts以及簡(jiǎn)單關(guān)系圖的點(diǎn)擊事件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
Vue實(shí)現(xiàn)的父組件向子組件傳值功能示例
這篇文章主要介紹了Vue實(shí)現(xiàn)的父組件向子組件傳值功能,結(jié)合完整實(shí)例形式簡(jiǎn)單分析了vue.js組件傳值的相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
vue Nprogress進(jìn)度條功能實(shí)現(xiàn)常見(jiàn)問(wèn)題
這篇文章主要介紹了vue Nprogress進(jìn)度條功能實(shí)現(xiàn),NProgress是頁(yè)面跳轉(zhuǎn)是出現(xiàn)在瀏覽器頂部的進(jìn)度條,本文通過(guò)實(shí)例代碼給大家講解,需要的朋友可以參考下2021-07-07
Vue中keep-alive 實(shí)現(xiàn)后退不刷新并保持滾動(dòng)位置
這篇文章主要介紹了Vue中keep-alive 實(shí)現(xiàn)后退不刷新并保持滾動(dòng)位置的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
vue中點(diǎn)擊下載圖片的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于vue中點(diǎn)擊下載圖片的實(shí)現(xiàn)方法,在Vue的模板中,我們可以將下載屬性綁定至或元素上,用來(lái)實(shí)現(xiàn)點(diǎn)擊下載,需要的朋友可以參考下2023-08-08
Vue3+TS+Vite+NaiveUI搭建一個(gè)項(xiàng)目骨架實(shí)現(xiàn)
本文主要介紹了Vue3+TS+Vite+NaiveUI搭建一個(gè)項(xiàng)目骨架實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06

