在实际开发中,直接将用户的明文密码传输到后端存在较大安全风险。为了提高安全性,常见的做法是在前端发送前先对密码进行 MD5 哈希,再用 AES 对称加密 进行二次加密,然后使用 application/x-www-form-urlencoded
格式发送给后端。本文将介绍如何在 Vue 项目中实现这一登录流程。
一、需求背景
后端要求登录接口接收三个字段:
account
:用户名password
:先 MD5 再 AES 加密的密码grant_type
:固定值'password'
接口需要使用 POST
方法,且 Content-Type
必须为 application/x-www-form-urlencoded
。
二、依赖安装
我们需要三个依赖库:
npm install qs js-md5 crypto-js
qs:将对象序列化为
key=value&key=value
格式js-md5:实现 MD5 哈希算法
crypto-js:实现 AES 对称加密
三、AES 加密工具封装
创建 src/utils/encrypt.js
:
import CryptoJS from 'crypto-js'
// 注意:key 和 iv 必须与后端保持一致
const key = CryptoJS.enc.Utf8.parse('1234567890abcdef') // 16 字节密钥
const iv = CryptoJS.enc.Utf8.parse('abcdef1234567890') // 16 字节向量
export const aesEncryption = {
encrypt(word) {
const srcs = CryptoJS.enc.Utf8.parse(word)
const encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.toString()
},
decrypt(ciphertext) {
const decrypted = CryptoJS.AES.decrypt(ciphertext, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
}
安全提示:生产环境中
key
和iv
不建议直接写死在前端,可通过后端下发、动态生成等方式提高安全性。
四、改造登录接口
src/api/auth.js
:
import qs from 'qs'
import request from '@/utils/request'
import { httpUri } from '@/config'
// 登录接口
export function login(data) {
return request({
url: `${httpUri}/api/oauth/Login`,
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: qs.stringify(data) // 转为 x-www-form-urlencoded 格式
})
}
五、调用示例
import md5 from 'js-md5'
import { aesEncryption } from '@/utils/encrypt'
import { login } from '@/api/auth'
import { ElMessage } from 'element-plus'
// 假设这是 Vue3 中的表单
const form = ref({
user: '',
password: ''
})
async function handleLogin() {
if (!form.value.user || !form.value.password) {
ElMessage.warning('请输入账号和密码')
return
}
try {
// 1. MD5 加密
const md5Pwd = md5(form.value.password)
// 2. AES 再加密
const encryptedPwd = aesEncryption.encrypt(md5Pwd)
// 3. 构造请求参数
const payload = {
account: form.value.user,
password: encryptedPwd,
grant_type: 'password'
}
// 4. 调用登录接口
const res = await login(payload)
// 5. 登录成功处理
console.log('登录成功', res.data)
ElMessage.success('登录成功')
} catch (err) {
console.error('登录失败', err)
ElMessage.error(err?.response?.data?.message || '登录失败')
}
}
六、执行流程图
用户输入密码
↓
MD5 哈希
↓
AES 加密 (key + iv)
↓
x-www-form-urlencoded 序列化
↓
POST 请求发送到后端
七、总结
通过 MD5 + AES 双重加密,我们在一定程度上减少了密码在传输过程中的风险;配合 application/x-www-form-urlencoded
提交格式,可以更好地适配一些后端框架的解析方式。
完整实现中需要注意:
key
和iv
必须与后端保持一致。加密并不能完全防止泄露,HTTPS 仍然是必不可少的传输加密手段。
如果想进一步简化调用,可以将加密逻辑放到
login
方法内部或请求拦截器中,调用时只传明文密码。