当前位置: 首页 > news >正文

【pure-admin】前端使用pure-admin后台管理系统框架,后端使用FastAPI的前端向后端加密发送用户登录密码的完整示例

在Pure-Admin前端框架和FastAPI后端之间如何加密传输用户登录密码。使用RSA非对称加密算法来确保密码安全。

实现方案概述

  1. 后端生成RSA密钥对,并提供接口返回公钥
  2. 前端获取公钥后,使用公钥加密用户密码
  3. 前端将加密后的密码发送到后端
  4. 后端使用私钥解密密码,进行验证

后端实现(FastAPI)

首先实现FastAPI后端,负责生成密钥对、提供公钥和处理登录请求:


```python
from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import rsa
import os
import json
import bcryptapp = FastAPI()# 允许跨域请求,适应前端开发
app.add_middleware(CORSMiddleware,allow_origins=["http://localhost:8080"],  # Pure-Admin默认端口allow_credentials=True,allow_methods=["*"],allow_headers=["*"],
)# 生成并保存RSA密钥对(首次运行时)
def generate_rsa_keys():if not os.path.exists("private.pem") or not os.path.exists("public.pem"):(pubkey, privkey) = rsa.newkeys(2048)with open("public.pem", "wb") as f:f.write(pubkey.save_pkcs1())with open("private.pem", "wb") as f:f.write(privkey.save_pkcs1())# 加载密钥
def load_keys():with open("public.pem", "rb") as f:pubkey = rsa.PublicKey.load_pkcs1(f.read())with open("private.pem", "rb") as f:privkey = rsa.PrivateKey.load_pkcs1(f.read())return pubkey, privkey# 初始化密钥
generate_rsa_keys()
pubkey, privkey = load_keys()# 模拟数据库中的用户(实际项目中应使用数据库)
fake_db = {"admin": {# 密码是"password123"的bcrypt哈希值"password_hash": "$2b$12$9T4R3QJZJZJZJZJZJZJZOeUQZJZJZJZJZJZJZJZJZJZJZJZJZ"}
}# 请求模型
class LoginRequest(BaseModel):username: strpassword: str  # 这里将是加密后的密码# 获取公钥接口
@app.get("/api/public-key", tags=["auth"])
async def get_public_key():with open("public.pem", "rb") as f:public_key = f.read().decode("utf-8")return {"public_key": public_key}# 登录接口
@app.post("/api/login", tags=["auth"])
async def login(login_data: LoginRequest):try:# 解密密码encrypted_password = login_data.password# 将加密的密码从base64字符串转换为字节encrypted_bytes = bytes.fromhex(encrypted_password)# 使用私钥解密decrypted_password = rsa.decrypt(encrypted_bytes, privkey).decode("utf-8")# 验证用户user = fake_db.get(login_data.username)if not user:raise HTTPException(status_code=401, detail="用户名或密码错误")# 验证密码(使用bcrypt)if not bcrypt.checkpw(decrypted_password.encode('utf-8'), user["password_hash"].encode('utf-8')):raise HTTPException(status_code=401, detail="用户名或密码错误")# 这里可以生成JWT令牌等return {"success": True,"message": "登录成功","token": "fake-jwt-token"  # 实际项目中应生成真实的JWT令牌}except Exception as e:raise HTTPException(status_code=400, detail=f"登录失败: {str(e)}")# 启动服务器
if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

前端实现(Pure-Admin)

接下来实现Pure-Admin前端部分,包括获取公钥、加密密码和发送登录请求:

<template><div class="login-container"><el-card class="login-card"><div slot="header" class="login-header"><h2>系统登录</h2></div><el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-width="80px"><el-form-item label="用户名" prop="username"><el-input v-model="loginForm.username" placeholder="请输入用户名"prefix-icon="User"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input v-model="loginForm.password" type="password" placeholder="请输入密码"prefix-icon="Lock"></el-input></el-form-item><el-form-item><el-button type="primary" class="login-btn" @click="handleLogin":loading="loading">登录</el-button></el-form-item></el-form></el-card></div>
</template><script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElForm } from 'element-plus';
import { useRouter } from 'vue-router';
import JSEncrypt from 'jsencrypt'; // 导入加密库
import { getPublicKey, userLogin } from '@/api/auth'; // 导入API// 登录表单数据
const loginForm = reactive({username: '',password: ''
});// 表单验证规则
const loginRules = {username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
};// 状态变量
const loading = ref(false);
const publicKey = ref('');
const loginFormRef = ref(null);
const router = useRouter();// 获取公钥
const fetchPublicKey = async () => {try {const response = await getPublicKey();publicKey.value = response.public_key;} catch (error) {ElMessage.error('获取加密公钥失败,请刷新页面重试');console.error('获取公钥失败:', error);}
};// 加密密码
const encryptPassword = (password) => {if (!publicKey.value) {ElMessage.warning('加密公钥尚未加载完成,请稍候');return null;}const encrypt = new JSEncrypt();encrypt.setPublicKey(publicKey.value);// 加密并转换为十六进制字符串(避免特殊字符问题)return encrypt.encrypt(password) ? encrypt.encrypt(password).toString('hex') : null;
};// 处理登录
const handleLogin = async () => {// 表单验证if (!loginFormRef.value) return;try {await loginFormRef.value.validate();} catch (error) {return;}// 加密密码const encryptedPwd = encryptPassword(loginForm.password);if (!encryptedPwd) {return;}// 发送登录请求loading.value = true;try {const response = await userLogin({username: loginForm.username,password: encryptedPwd // 发送加密后的密码});if (response.success) {ElMessage.success('登录成功');// 保存tokenlocalStorage.setItem('token', response.token);// 跳转到首页router.push('/');} else {ElMessage.error(response.message || '登录失败');}} catch (error) {ElMessage.error('登录请求失败,请稍后重试');console.error('登录错误:', error);} finally {loading.value = false;}
};// 页面加载时获取公钥
onMounted(() => {fetchPublicKey();
});
</script><style scoped>
.login-container {display: flex;justify-content: center;align-items: center;min-height: 100vh;background-color: #f5f7fa;
}.login-card {width: 400px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}.login-header {text-align: center;
}.login-btn {width: 100%;
}
</style>

实现说明

  1. 后端依赖安装

    pip install fastapi uvicorn rsa bcrypt python-multipart
    
  2. 前端依赖安装

    npm install jsencrypt
    
  3. 安全要点

    • 使用RSA非对称加密,公钥在前端加密,私钥仅在后端解密
    • 密码在传输过程中始终是加密状态,不会暴露明文
    • 后端存储的是密码的bcrypt哈希值,而非明文
    • 结合了HTTPS会更加安全(示例中为了开发方便未包含)
  4. 工作流程

    • 前端页面加载时获取公钥
    • 用户输入用户名和密码后,前端使用公钥加密密码
    • 前端发送加密后的密码到后端
    • 后端使用私钥解密密码,与数据库中的哈希值比对
    • 验证成功后返回登录结果和令牌

这个示例可以直接集成到Pure-Admin和FastAPI项目中,确保用户密码在传输过程中的安全性。在实际生产环境中,还可以添加更多安全措施,如定期更换密钥对、添加验证码等。

ps:本文借助ai生成,仅供参考


文章转载自:

http://jfLl4COF.npkrm.cn
http://zGB0H1TV.npkrm.cn
http://wxngnQ8L.npkrm.cn
http://NWwescZr.npkrm.cn
http://rfub0SQi.npkrm.cn
http://cFddegnT.npkrm.cn
http://Fiu0Dot4.npkrm.cn
http://0l3RFwoK.npkrm.cn
http://BZplGIgy.npkrm.cn
http://XA7dtg0T.npkrm.cn
http://t20r86Os.npkrm.cn
http://OSh7fAwe.npkrm.cn
http://lvhR4fwb.npkrm.cn
http://i0YSR9Ht.npkrm.cn
http://2X4m0uNs.npkrm.cn
http://bI7Uf4Qm.npkrm.cn
http://rOvNYSry.npkrm.cn
http://c2KHtMp8.npkrm.cn
http://5GiXWp0I.npkrm.cn
http://pMGf9DUe.npkrm.cn
http://UZPsTulx.npkrm.cn
http://eMWWi0X1.npkrm.cn
http://4uftzFd5.npkrm.cn
http://7ElHS2Ze.npkrm.cn
http://M3pvUGMZ.npkrm.cn
http://DGkeIreC.npkrm.cn
http://EMueFOX1.npkrm.cn
http://46MybtIf.npkrm.cn
http://bMLJq85y.npkrm.cn
http://3GhL9LGU.npkrm.cn
http://www.dtcms.com/a/386277.html

相关文章:

  • 从 Node.js 安装到 Vue 3 开发环境搭建
  • Python单元测试框架之pytest -- 生成测试报告
  • 使用HBuilderX新建uniapp项目
  • 医疗行业安全合规数据管理平台:构建高效协作与集中化知识沉淀的一体化解决方案
  • 从一次鼠标点击窥探操作系统内核:中断、驱动、IPC与内存安全的奇幻之旅
  • 【超详细】C#的单例模式
  • 加快 NoETL 数据工程实践, Aloudata 荣登《2025 中国数智化转型升级创新服务企业》榜单
  • 香港服务器CN2带宽价格多少钱?很贵吗?
  • 180 课时吃透 Go 语言游戏后端系列1:第一个Go程序
  • MSI 与 IOAPIC LAPIC 如何协作,操作系统如何初始化和使用他们
  • 数据库优化(六)安全字段脱敏设计—东方仙盟金丹期
  • java21学习笔记
  • 大厂综合题库解析
  • 算法奇妙屋(2)-模拟
  • 贪心算法应用:区间调度问题详解
  • js中异步编程的实现方式【详细】
  • 详解 ArduPilot:开源无人机自动驾驶系统的全方位解析
  • 分页查询:时间筛选+日期筛选+增加queryWrapper 筛选条件
  • 通透理清三级缓存--看Spring是如何解决循环依赖的
  • 【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
  • 查看 Docker 守护进程日志
  • 第11章 [特殊字符]️Hutool 常用工具类
  • 【MySQL|第十篇】总结篇——各种命令集合
  • npm : 无法加载文件 d:\nvm4w\nodejs\npm.ps1,
  • 贪心算法应用:活动选择问题详解
  • C++ 模板:以简御繁-5/5
  • AI大模型学习(6)Yolo V8神经网络的基础应用
  • 【完整源码+数据集+部署教程】残疾人和正常人识别图像分割系统: yolov8-seg-act
  • 深度学习:从概念到实践,开启智能时代新篇章
  • 构建AI智能体:三十五、决策树的核心机制(一):刨根问底鸢尾花分类中的参数推理计算