在Vue前端實(shí)現(xiàn)登錄密碼加密傳輸?shù)娜鞒?/h1>
更新時(shí)間:2026年03月27日 09:28:48 作者:前端小趴菜05
本文介紹在Vue3前端實(shí)現(xiàn)登錄密碼加密傳輸?shù)姆椒?使用非對(duì)稱加密算法RSA或ECC,前端使用公鑰加密密碼,后端使用私鑰解密,提供了實(shí)現(xiàn)方案,包括核心流程設(shè)計(jì)、前置準(zhǔn)備、Vue3代碼實(shí)現(xiàn)步驟以及后端配合要點(diǎn),需要的朋友可以參考下
在 Vue 3 前端實(shí)現(xiàn)登錄密碼加密傳輸,核心目標(biāo)是防止密碼以明文形式在網(wǎng)絡(luò)中傳輸(避免被中間人竊 聽(tīng),盡管 HTTPS 是基礎(chǔ),但在高安全要求場(chǎng)景下通常需要應(yīng)用層二次加密)。
最常見(jiàn)的方案是:前端使用公鑰加密密碼 -> 后端使用私鑰解密。通常采用非對(duì)稱加密算法 RSA 或 ECC。
以下是基于 Vue 3 + TypeScript + rsaencrypt (或 jsencrypt) 的完整實(shí)現(xiàn)方案。
1. 核心流程設(shè)計(jì)
- 后端生成密鑰對(duì):后端生成 RSA 公鑰和私鑰。
- 獲取公鑰:前端在登錄頁(yè)面加載時(shí)(或用戶點(diǎn)擊登錄前),調(diào)用接口獲取后端的公鑰(也可以由后端定期輪換,通過(guò)接口下發(fā))。
- 前端加密:用戶使用
jsencrypt 或 node-rsa 等庫(kù),利用公鑰對(duì)密碼進(jìn)行加密。 - 發(fā)送請(qǐng)求:將加密后的密文(通常是 Base64 字符串)發(fā)送給后端。
- 后端解密:后端使用私鑰解密密文,得到原始密碼,再進(jìn)行哈希比對(duì)(如 BCrypt/Argon2)驗(yàn)證登錄。
2. 前置準(zhǔn)備
安裝加密庫(kù)。推薦使用 jsencrypt (輕量,專為瀏覽器設(shè)計(jì)) 或 encryptlong (如果密碼很長(zhǎng),標(biāo)準(zhǔn) RSA 有長(zhǎng)度限制,但密碼通常很短,jsencrypt 足夠)。
npm install jsencrypt
# 或者
yarn add jsencrypt
3. Vue 3 代碼實(shí)現(xiàn)
步驟一:創(chuàng)建加密工具類 (src/utils/rsaEncrypt.ts)
封裝加密邏輯,方便復(fù)用。
// src/utils/rsaEncrypt.ts
import JSEncrypt from 'jsencrypt';
// 注意:實(shí)際項(xiàng)目中,公鑰通常從后端接口動(dòng)態(tài)獲取,而不是寫死在這里
// 這里為了演示,先假設(shè)有一個(gè)默認(rèn)公鑰,實(shí)際請(qǐng)看步驟二中的動(dòng)態(tài)獲取
const DEFAULT_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD... (你的后端公鑰) ...==
-----END PUBLIC KEY-----`;
/**
* 使用公鑰加密字符串
* @param text 待加密的明文(密碼)
* @param publicKey 公鑰,如果不傳則使用默認(rèn)值(建議動(dòng)態(tài)傳入)
*/
export function encryptPassword(text: string, publicKey?: string): string {
const encryptor = new JSEncrypt();
// 設(shè)置公鑰
encryptor.setPublicKey(publicKey || DEFAULT_PUBLIC_KEY);
// 執(zhí)行加密
const encrypted = encryptor.encrypt(text);
if (!encrypted) {
throw new Error('密碼加密失敗');
}
return encrypted;
}
步驟二:在登錄組件中使用 (src/views/Login.vue)
在實(shí)際場(chǎng)景中,強(qiáng)烈建議在登錄頁(yè)初始化時(shí)調(diào)用后端接口獲取最新的公鑰,以防重放攻擊或密鑰輪換。
<template>
<div class="login-container">
<h2>用戶登錄</h2>
<form @submit.prevent="handleLogin">
<div class="form-item">
<label>用戶名:</label>
<input v-model="loginForm.username" type="text" required />
</div>
<div class="form-item">
<label>密碼:</label>
<!-- 輸入框本身可以是 type="password" 隱藏顯示,但這不影響傳輸加密 -->
<input v-model="loginForm.password" type="password" required />
</div>
<button type="submit" :disabled="loading">
{{ loading ? '登錄中...' : '登錄' }}
</button>
</form>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { encryptPassword } from '@/utils/rsaEncrypt';
// 假設(shè)你有一個(gè) axios 實(shí)例
import request from '@/utils/request';
const loading = ref(false);
const publicKey = ref<string>('');
const loginForm = reactive({
username: '',
password: ''
});
// 1. 頁(yè)面加載時(shí)獲取后端公鑰
const fetchPublicKey = async () => {
try {
// 模擬接口:/api/auth/public-key
const res = await request.get('/auth/public-key');
// 假設(shè)后端返回格式 { code: 200, data: "-----BEGIN PUBLIC KEY-----..." }
publicKey.value = res.data;
console.log('公鑰已獲取');
} catch (error) {
console.error('獲取公鑰失敗', error);
// 降級(jí)策略:如果獲取失敗,是否允許登錄?通常高安場(chǎng)景應(yīng)禁止
}
};
// 2. 處理登錄
const handleLogin = async () => {
if (!loginForm.username || !loginForm.password) {
alert('請(qǐng)輸入用戶名和密碼');
return;
}
if (!publicKey.value) {
alert('系統(tǒng)安全組件未加載,請(qǐng)稍后重試');
return;
}
loading.value = true;
try {
// 【核心步驟】前端加密密碼
const encryptedPassword = encryptPassword(loginForm.password, publicKey.value);
// 構(gòu)造發(fā)送數(shù)據(jù),注意發(fā)送的是加密后的字符串
const payload = {
username: loginForm.username,
password: encryptedPassword,
// 可選:有些方案會(huì)帶上時(shí)間戳或隨機(jī)鹽值防止重放攻擊
// timestamp: Date.now()
};
// 發(fā)送登錄請(qǐng)求
const res = await request.post('/auth/login', payload);
if (res.code === 200) {
alert('登錄成功');
// 存儲(chǔ) token 等操作
// localStorage.setItem('token', res.data.token);
} else {
alert(res.message || '登錄失敗');
}
} catch (error) {
console.error('登錄異常', error);
alert('登錄失敗,請(qǐng)檢查網(wǎng)絡(luò)或聯(lián)系管理員');
} finally {
loading.value = false;
// 安全起見(jiàn),加密后立即清空明文密碼
loginForm.password = '';
}
};
onMounted(() => {
fetchPublicKey();
});
</script>
<style scoped>
/* 簡(jiǎn)單樣式 */
.login-container { max-width: 400px; margin: 50px auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; }
.form-item { margin-bottom: 15px; }
input { width: 100%; padding: 8px; box-sizing: border-box; }
button { width: 100%; padding: 10px; background: #42b983; color: white; border: none; cursor: pointer; }
button:disabled { background: #ccc; }
</style>
4. 后端配合要點(diǎn) (簡(jiǎn)述)
前端做了加密,后端必須能解密,否則無(wú)法驗(yàn)證。
生成密鑰對(duì):
- 后端啟動(dòng)時(shí)生成一對(duì) RSA 密鑰(或使用固定的密鑰對(duì)存儲(chǔ)在配置中心/數(shù)據(jù)庫(kù)中)。
- 私鑰:嚴(yán)格保存在后端服務(wù)器內(nèi)存或安全存儲(chǔ)中,絕不暴露給前端。
- 公鑰:提供給前端接口下載。
提供公鑰接口:
- 接口示例:
GET /api/auth/public-key - 返回 PEM 格式的公鑰字符串。
登錄接口解密:
- 接收前端傳來(lái)的
encryptedPassword。 - 使用私鑰進(jìn)行解密,得到原始密碼
rawPassword。 - 重要:拿到
rawPassword 后,不要直接跟數(shù)據(jù)庫(kù)里的明文比(數(shù)據(jù)庫(kù)里存的應(yīng)該是加鹽哈希值,如 BCrypt)。 - 流程:
解密得到明文 -> 使用同樣的哈希算法(如BCrypt)計(jì)算哈希 -> 與數(shù)據(jù)庫(kù)哈希值比對(duì)。
以上就是在Vue前端實(shí)現(xiàn)登錄密碼加密傳輸?shù)娜鞒痰脑敿?xì)內(nèi)容,更多關(guān)于Vue登錄密碼加密傳輸?shù)馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
-
vite2.0+vue3移動(dòng)端項(xiàng)目實(shí)戰(zhàn)詳解
這篇文章主要介紹了vite2.0+vue3移動(dòng)端項(xiàng)目實(shí)戰(zhàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧 2021-03-03
-
sublime如何配置開(kāi)發(fā)VUE環(huán)境自動(dòng)格式化代碼
這篇文章主要介紹了sublime如何配置開(kāi)發(fā)VUE環(huán)境自動(dòng)格式化代碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2024-03-03
-
從零開(kāi)始在vue-cli4配置自適應(yīng)vw布局的實(shí)現(xiàn)
這篇文章主要介紹了從零開(kāi)始在vue-cli4配置自適應(yīng)vw布局,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧 2020-06-06
-
Vue.js 2.0 移動(dòng)端拍照壓縮圖片上傳預(yù)覽功能
這篇文章主要介紹了Vue.js 2.0 移動(dòng)端拍照壓縮圖片上傳預(yù)覽功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下 2017-03-03
-
Vue使用antd中input組件去驗(yàn)證輸入框輸入內(nèi)容(rules?案例)
這篇文章主要介紹了Vue使用antd中input組件去驗(yàn)證輸入框輸入內(nèi)容-rules-案例,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2022-06-06
-
vue3在table里使用elementUI的form表單驗(yàn)證的示例代碼
這篇文章主要介紹了vue3在table里使用elementUI的form表單驗(yàn)證的示例代碼,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2023-12-12
-
vue3中處理不同數(shù)據(jù)結(jié)構(gòu)JSON的實(shí)現(xiàn)
本文主要介紹了vue3中處理不同數(shù)據(jù)結(jié)構(gòu)JSON的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧 2023-06-06
-
詳解Vue實(shí)現(xiàn)鏈接生成二維碼并支持下載
在現(xiàn)代 Web 應(yīng)用中,快速分享鏈接是一項(xiàng)常見(jiàn)需求,二維碼作為一種簡(jiǎn)潔的分享方式,受到了廣泛歡迎,所以本文將介紹如何使用 Vue 純前端技術(shù)實(shí)現(xiàn)動(dòng)態(tài)生成鏈接二維碼的方法,需要的可以參考下 2024-03-03
最新評(píng)論
在 Vue 3 前端實(shí)現(xiàn)登錄密碼加密傳輸,核心目標(biāo)是防止密碼以明文形式在網(wǎng)絡(luò)中傳輸(避免被中間人竊 聽(tīng),盡管 HTTPS 是基礎(chǔ),但在高安全要求場(chǎng)景下通常需要應(yīng)用層二次加密)。
最常見(jiàn)的方案是:前端使用公鑰加密密碼 -> 后端使用私鑰解密。通常采用非對(duì)稱加密算法 RSA 或 ECC。
以下是基于 Vue 3 + TypeScript + rsaencrypt (或 jsencrypt) 的完整實(shí)現(xiàn)方案。
1. 核心流程設(shè)計(jì)
- 后端生成密鑰對(duì):后端生成 RSA 公鑰和私鑰。
- 獲取公鑰:前端在登錄頁(yè)面加載時(shí)(或用戶點(diǎn)擊登錄前),調(diào)用接口獲取后端的公鑰(也可以由后端定期輪換,通過(guò)接口下發(fā))。
- 前端加密:用戶使用
jsencrypt或node-rsa等庫(kù),利用公鑰對(duì)密碼進(jìn)行加密。 - 發(fā)送請(qǐng)求:將加密后的密文(通常是 Base64 字符串)發(fā)送給后端。
- 后端解密:后端使用私鑰解密密文,得到原始密碼,再進(jìn)行哈希比對(duì)(如 BCrypt/Argon2)驗(yàn)證登錄。
2. 前置準(zhǔn)備
安裝加密庫(kù)。推薦使用 jsencrypt (輕量,專為瀏覽器設(shè)計(jì)) 或 encryptlong (如果密碼很長(zhǎng),標(biāo)準(zhǔn) RSA 有長(zhǎng)度限制,但密碼通常很短,jsencrypt 足夠)。
npm install jsencrypt # 或者 yarn add jsencrypt
3. Vue 3 代碼實(shí)現(xiàn)
步驟一:創(chuàng)建加密工具類 (src/utils/rsaEncrypt.ts)
封裝加密邏輯,方便復(fù)用。
// src/utils/rsaEncrypt.ts
import JSEncrypt from 'jsencrypt';
// 注意:實(shí)際項(xiàng)目中,公鑰通常從后端接口動(dòng)態(tài)獲取,而不是寫死在這里
// 這里為了演示,先假設(shè)有一個(gè)默認(rèn)公鑰,實(shí)際請(qǐng)看步驟二中的動(dòng)態(tài)獲取
const DEFAULT_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD... (你的后端公鑰) ...==
-----END PUBLIC KEY-----`;
/**
* 使用公鑰加密字符串
* @param text 待加密的明文(密碼)
* @param publicKey 公鑰,如果不傳則使用默認(rèn)值(建議動(dòng)態(tài)傳入)
*/
export function encryptPassword(text: string, publicKey?: string): string {
const encryptor = new JSEncrypt();
// 設(shè)置公鑰
encryptor.setPublicKey(publicKey || DEFAULT_PUBLIC_KEY);
// 執(zhí)行加密
const encrypted = encryptor.encrypt(text);
if (!encrypted) {
throw new Error('密碼加密失敗');
}
return encrypted;
}步驟二:在登錄組件中使用 (src/views/Login.vue)
在實(shí)際場(chǎng)景中,強(qiáng)烈建議在登錄頁(yè)初始化時(shí)調(diào)用后端接口獲取最新的公鑰,以防重放攻擊或密鑰輪換。
<template>
<div class="login-container">
<h2>用戶登錄</h2>
<form @submit.prevent="handleLogin">
<div class="form-item">
<label>用戶名:</label>
<input v-model="loginForm.username" type="text" required />
</div>
<div class="form-item">
<label>密碼:</label>
<!-- 輸入框本身可以是 type="password" 隱藏顯示,但這不影響傳輸加密 -->
<input v-model="loginForm.password" type="password" required />
</div>
<button type="submit" :disabled="loading">
{{ loading ? '登錄中...' : '登錄' }}
</button>
</form>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { encryptPassword } from '@/utils/rsaEncrypt';
// 假設(shè)你有一個(gè) axios 實(shí)例
import request from '@/utils/request';
const loading = ref(false);
const publicKey = ref<string>('');
const loginForm = reactive({
username: '',
password: ''
});
// 1. 頁(yè)面加載時(shí)獲取后端公鑰
const fetchPublicKey = async () => {
try {
// 模擬接口:/api/auth/public-key
const res = await request.get('/auth/public-key');
// 假設(shè)后端返回格式 { code: 200, data: "-----BEGIN PUBLIC KEY-----..." }
publicKey.value = res.data;
console.log('公鑰已獲取');
} catch (error) {
console.error('獲取公鑰失敗', error);
// 降級(jí)策略:如果獲取失敗,是否允許登錄?通常高安場(chǎng)景應(yīng)禁止
}
};
// 2. 處理登錄
const handleLogin = async () => {
if (!loginForm.username || !loginForm.password) {
alert('請(qǐng)輸入用戶名和密碼');
return;
}
if (!publicKey.value) {
alert('系統(tǒng)安全組件未加載,請(qǐng)稍后重試');
return;
}
loading.value = true;
try {
// 【核心步驟】前端加密密碼
const encryptedPassword = encryptPassword(loginForm.password, publicKey.value);
// 構(gòu)造發(fā)送數(shù)據(jù),注意發(fā)送的是加密后的字符串
const payload = {
username: loginForm.username,
password: encryptedPassword,
// 可選:有些方案會(huì)帶上時(shí)間戳或隨機(jī)鹽值防止重放攻擊
// timestamp: Date.now()
};
// 發(fā)送登錄請(qǐng)求
const res = await request.post('/auth/login', payload);
if (res.code === 200) {
alert('登錄成功');
// 存儲(chǔ) token 等操作
// localStorage.setItem('token', res.data.token);
} else {
alert(res.message || '登錄失敗');
}
} catch (error) {
console.error('登錄異常', error);
alert('登錄失敗,請(qǐng)檢查網(wǎng)絡(luò)或聯(lián)系管理員');
} finally {
loading.value = false;
// 安全起見(jiàn),加密后立即清空明文密碼
loginForm.password = '';
}
};
onMounted(() => {
fetchPublicKey();
});
</script>
<style scoped>
/* 簡(jiǎn)單樣式 */
.login-container { max-width: 400px; margin: 50px auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; }
.form-item { margin-bottom: 15px; }
input { width: 100%; padding: 8px; box-sizing: border-box; }
button { width: 100%; padding: 10px; background: #42b983; color: white; border: none; cursor: pointer; }
button:disabled { background: #ccc; }
</style>4. 后端配合要點(diǎn) (簡(jiǎn)述)
前端做了加密,后端必須能解密,否則無(wú)法驗(yàn)證。
生成密鑰對(duì):
- 后端啟動(dòng)時(shí)生成一對(duì) RSA 密鑰(或使用固定的密鑰對(duì)存儲(chǔ)在配置中心/數(shù)據(jù)庫(kù)中)。
- 私鑰:嚴(yán)格保存在后端服務(wù)器內(nèi)存或安全存儲(chǔ)中,絕不暴露給前端。
- 公鑰:提供給前端接口下載。
提供公鑰接口:
- 接口示例:
GET /api/auth/public-key - 返回 PEM 格式的公鑰字符串。
登錄接口解密:
- 接收前端傳來(lái)的
encryptedPassword。 - 使用私鑰進(jìn)行解密,得到原始密碼
rawPassword。 - 重要:拿到
rawPassword后,不要直接跟數(shù)據(jù)庫(kù)里的明文比(數(shù)據(jù)庫(kù)里存的應(yīng)該是加鹽哈希值,如 BCrypt)。 - 流程:
解密得到明文->使用同樣的哈希算法(如BCrypt)計(jì)算哈希->與數(shù)據(jù)庫(kù)哈希值比對(duì)。
以上就是在Vue前端實(shí)現(xiàn)登錄密碼加密傳輸?shù)娜鞒痰脑敿?xì)內(nèi)容,更多關(guān)于Vue登錄密碼加密傳輸?shù)馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vite2.0+vue3移動(dòng)端項(xiàng)目實(shí)戰(zhàn)詳解
這篇文章主要介紹了vite2.0+vue3移動(dòng)端項(xiàng)目實(shí)戰(zhàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
sublime如何配置開(kāi)發(fā)VUE環(huán)境自動(dòng)格式化代碼
這篇文章主要介紹了sublime如何配置開(kāi)發(fā)VUE環(huán)境自動(dòng)格式化代碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
從零開(kāi)始在vue-cli4配置自適應(yīng)vw布局的實(shí)現(xiàn)
這篇文章主要介紹了從零開(kāi)始在vue-cli4配置自適應(yīng)vw布局,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Vue.js 2.0 移動(dòng)端拍照壓縮圖片上傳預(yù)覽功能
這篇文章主要介紹了Vue.js 2.0 移動(dòng)端拍照壓縮圖片上傳預(yù)覽功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03
Vue使用antd中input組件去驗(yàn)證輸入框輸入內(nèi)容(rules?案例)
這篇文章主要介紹了Vue使用antd中input組件去驗(yàn)證輸入框輸入內(nèi)容-rules-案例,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
vue3在table里使用elementUI的form表單驗(yàn)證的示例代碼
這篇文章主要介紹了vue3在table里使用elementUI的form表單驗(yàn)證的示例代碼,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-12-12
vue3中處理不同數(shù)據(jù)結(jié)構(gòu)JSON的實(shí)現(xiàn)
本文主要介紹了vue3中處理不同數(shù)據(jù)結(jié)構(gòu)JSON的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
詳解Vue實(shí)現(xiàn)鏈接生成二維碼并支持下載
在現(xiàn)代 Web 應(yīng)用中,快速分享鏈接是一項(xiàng)常見(jiàn)需求,二維碼作為一種簡(jiǎn)潔的分享方式,受到了廣泛歡迎,所以本文將介紹如何使用 Vue 純前端技術(shù)實(shí)現(xiàn)動(dòng)態(tài)生成鏈接二維碼的方法,需要的可以參考下2024-03-03

