注册登录后上传文件到本地数据库项目
在上一篇的基础上我有添加了登录注册功能文件上传
更新一下代码添加登录注册功能
app.js
// app.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const db = require('./models/db');
const User = require('./models/userModel');
const File = require('./models/fileModel');
const uploadRoutes = require('./routes/upload');
const authRoutes = require('./routes/auth');const app = express();
const PORT = 5000;// 中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));// 路由
app.use('/upload', uploadRoutes);
app.use('/auth', authRoutes);// 同步数据库
db.sync().then(() => {console.log('数据库连接成功...');
}).catch(err => console.log('错误: ' + err));app.listen(PORT, () => {console.log(`服务器正在运行在 http://localhost:${PORT}`);
});
// routes/auth.js
// routes/auth.js
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/userModel');const router = express.Router();
const secret = 'your_jwt_secret';// 用户注册
router.post('/register', async (req, res) => {try {const { username, password } = req.body;const hashedPassword = await bcrypt.hash(password, 10);const newUser = await User.create({ username, password: hashedPassword });res.status(201).json({ message: '用户注册成功', user: newUser });} catch (error) {res.status(500).json({ message: '注册失败', error });}
});// 用户登录
router.post('/login', async (req, res) => {try {const { username, password } = req.body;const user = await User.findOne({ where: { username } });if (!user) {return res.status(404).json({ message: '用户不存在' });}const isPasswordValid = await bcrypt.compare(password, user.password);if (!isPasswordValid) {return res.status(401).json({ message: '密码错误' });}const token = jwt.sign({ userId: user.id }, secret, { expiresIn: '1h' });res.status(200).json({ message: '登录成功', token });} catch (error) {res.status(500).json({ message: '登录失败', error });}
});module.exports = router;
// models/userModel.js
// models/userModel.js
const { Sequelize, DataTypes } = require('sequelize');
const db = require('./db');const User = db.define('User', {username: {type: DataTypes.STRING,allowNull: false,unique: true},password: {type: DataTypes.STRING,allowNull: false}
});module.exports = User;
<!-- src/components/Login.vue -->
<!-- src/components/Login.vue -->
<template><div><h2>用户登录</h2><form @submit.prevent="login"><div><label for="username">用户名:</label><input type="text" id="username" v-model="username" required /></div><div><label for="password">密码:</label><input type="password" id="password" v-model="password" required /></div><button type="submit">登录</button></form></div>
</template><script>
export default {data() {return {username: '',password: ''};},methods: {async login() {try {const response = await fetch('http://localhost:5000/auth/login', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ username: this.username, password: this.password })});const data = await response.json();if (response.ok) {localStorage.setItem('token', data.token);alert('登录成功!');this.$router.push('/upload');} else {alert('登录失败:' + data.message);}} catch (error) {alert('登录失败:' + error.message);}}}
};
</script>
<!-- src/components/Register.vue -->
<!-- src/components/Register.vue -->
<template><div><h2>用户注册</h2><form @submit.prevent="register"><div><label for="username">用户名:</label><input type="text" id="username" v-model="username" required /></div><div><label for="password">密码:</label><input type="password" id="password" v-model="password" required /></div><button type="submit">注册</button></form></div>
</template><script>
export default {data() {return {username: '',password: ''};},methods: {async register() {try {const response = await fetch('http://localhost:5000/auth/register', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ username: this.username, password: this.password })});const data = await response.json();if (response.ok) {alert('注册成功!');} else {alert('注册失败:' + data.message);}} catch (error) {alert('注册失败:' + error.message);}}}
};
</script>
// src/router/index.js
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Register from '../components/Register.vue';
import Login from '../components/Login.vue';
import FileUpload from '../components/FileUpload.vue';const routes = [{ path: '/register', component: Register },{ path: '/login', component: Login },{ path: '/upload', component: FileUpload, meta: { requiresAuth: true } }
];const router = createRouter({history: createWebHistory(),routes
});// 导航守卫
router.beforeEach((to, from, next) => {const loggedIn = localStorage.getItem('user');if (to.matched.some(record => record.meta.requiresAuth) && !loggedIn) {next('/login');} else {next();}
});export default router;
app.vue
<template><div id="app"><header><h1>我的应用</h1><nav v-if="!loggedIn"><ul><li @click="goTo('/login')">登录</li><li @click="goTo('/register')">注册</li></ul></nav><nav v-else><ul><li @click="goTo('/upload')">文件上传</li><li @click="logout">退出</li></ul></nav></header><main><router-view></router-view></main></div>
</template><script>
export default {data() {return {loggedIn: false};},created() {// 检查本地存储中是否有用户登录信息const token = localStorage.getItem('token');if (token) {this.loggedIn = true;}},methods: {goTo(path) {this.$router.push(path);},logout() {localStorage.removeItem('token');this.loggedIn = false;this.$router.push('/login');}}
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;text-align: center;color: #2c3e50;margin-top: 60px;
}header {background-color: #35495e;padding: 10px 0;color: white;
}nav ul {list-style: none;padding: 0;
}nav ul li {display: inline;margin: 0 10px;cursor: pointer;
}
</style>
// src/main.js
// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import { createRouter, createWebHistory } from 'vue-router';
import Register from './components/Register.vue';
import Login from './components/Login.vue';
import FileUpload from './components/FileUpload.vue';const routes = [{ path: '/register', component: Register },{ path: '/login', component: Login },{ path: '/upload', component: FileUpload }
];const router = createRouter({history: createWebHistory(),routes
});const app = createApp(App);
app.use(router);
app.mount('#app');
记得安装对应的包和更新依赖!!!
请记得一键三连(点赞、收藏、分享)哦!
相关文章:
注册登录后上传文件到本地数据库项目
在上一篇的基础上我有添加了登录注册功能文件上传 更新一下代码添加登录注册功能 app.js // app.js const express require(express); const bodyParser require(body-parser); const cors require(cors); const db require(./models/db); const User require(./models…...

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十三)-更换无人机控制器
引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…...

react 组件通信 —— 父子传值 【 函数式/类式 】
1、函数式组件通信 父子间通信 —— 父传子 父组件 export default function father() {return (<div style{{width:400px,height:200px,background:pink,marginLeft:500px}}>我是父组件<hr /><Son name{"韩小刀"}/></div>) } 子组件 ex…...
【SpringBoot】95、SpringBoot中使用MyBatis-Plus实现自动加密存储和查询自动解密
有的业务需要将敏感数据加密存储到 DB,如果我们每个都手动去加密,再设值,再保存 DB,不仅麻烦,还对开发者不友好,在 MyBatis-Plus 中我们可以使用 BaseTypeHandler 来解决这个问题 1、新增 TypeHandler import com.baomidou.mybatisplus.core.toolkit.AES; import com.b…...

[数仓]十二、离线数仓(Atlas元数据管理)
第1章 Atlas入门 1.1 Atlas概述 Apache Atlas为组织提供开放式元数据管理和治理功能,用以构建其数据资产目录,对这些资产进行分类和管理,并为数据分析师和数据治理团队,提供围绕这些数据资产的协作功能。 Atlas的具体功能如下: 元数据分类 支持对元数据进行分类管理,例…...

机器学习——决策树(笔记)
目录 一、认识决策树 1. 介绍 2. 决策树生成过程 二、sklearn中的决策树 1. tree.DecisionTreeClassifier(分类树) (1)模型基本参数 (2)模型属性 (3)接口 2. tree.Decision…...
翁恺-C语言程序设计-08-1. 求一批整数中出现最多的个位数字
08-1. 求一批整数中出现最多的个位数字 给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。 输入格式: 输入在第1行中…...

ROM修改进阶教程------深度解析小米设备锁机型不解锁bl 刷写特殊类固件的步骤
在玩机过程中会遇到很多自己机型忘记密码或者手机号不用导致机型出现账号锁。无法正常使用。那么此类机型如果无法正常售后解锁。只能通过第三方渠道。例如在早期小米机型有强解bl锁资源。然后刷入完美解锁包。这种可以登陆新账号。但后期新机型只能通过修改分区来屏蔽原设备锁…...

论文翻译 | LEAST-TO-MOST: 从最少到最多的提示使大型语言模型中的复杂推理成为可能
摘要 思维链提示(Chain-of-thought prompting)在多种自然语言推理任务上展现了卓越的性能。然而,在需要解决的问题比提示中展示的示例更难的任务上,它的表现往往不佳。为了克服从简单到困难的泛化挑战,我们提出了一种新…...
【区块链 + 智慧政务】都江堰区块链公共服务应用平台 | FISCO BCOS应用案例
都江堰区块链公共服务应用平台是四川开源观科技有限公司运用 FISCO BCOS 区块链技术为都江堰市建设的市级 区块链节点平台,该平台上线运营一年以来已在政务服务、社区养老和慈善公益领域落地 3 个应用,上链数据超 过 30 万条。 区块链 政务服务应用&am…...

Python从0到100(三十九):数据提取之正则(文末免费送书)
前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…...

redis redisson(仅供自己参考)
redis 通过setnx实现的分布式锁有问题 如图: 解决的新的工具为(闪亮登场):redisson redisson可重入锁的原理 实现语言lua: 加锁实现脚本语言: 释放锁的脚本语言: 加锁的lua -- 首先判断这个锁…...

【C语言初阶】探索编程基础:深入理解分支与循环语句的奥秘
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C语言 “ 登神长阶 ” 🤡往期回顾🤡:C语言入门 🌹🌹期待您的关注 🌹🌹 ❀分支与循环语句 📒1.…...

ERP基础知识
ERP 一、概述 ERP是Event-related Potentials的简称。外加一种特定的刺激,作用于感觉系统或脑 的某一部位,在给予刺激或撤销刺激时,或和当某种心理因素出现时在脑区所产生的电位变化,成为事件相关电位,是一种特殊…...
C++是否可以使用.获取union、struct中的成员变量的地址
C可以使用.获取union、struct中的成员变量的地址 示例代码如下所示 #include <stdio.h> #include <stdint.h>struct u128 { uint64_t v64; uint64_t v0; };int main() {union { unsigned __int128 ui; struct u128 s; } union_temp_m128;void* p1 &union_te…...

【前端】包管理器:npm、Yarn 和 pnpm 的全面比较
前端开发中的包管理器:npm、Yarn 和 pnpm 的全面比较 在现代前端开发中,包管理器是开发者必不可少的工具。它们不仅能帮我们管理项目的依赖,还能极大地提高开发效率。本文将详细介绍三种主流的前端包管理器:npm、Yarn 和 pnpm&am…...

C++ 类和对象 赋值运算符重载
前言: 在上文我们知道数据类型分为自定义类型和内置类型,当我想用内置类型比较大小是非常容易的但是在C中成员变量都是在类(自定义类型)里面的,那我想给类比较大小那该怎么办呢?这时候运算符重载就出现了 一 运算符重载概念&…...
【Python实战因果推断】35_双重差分6
目录 Strict Exogeneity No Time Varying Confounders No Feedback No Carryover and No Lagged Dependent Variable Strict Exogeneity 严格的外生性假设是一个相当技术性的假设,通常用固定效应模型的残差来表示: 严格的异质性说明: 这…...

【HarmonyOS】关于官方推荐的组件级路由Navigation的心得体会
前言 最近因为之前的630版本有点忙,导致断更了几天,现在再补上。换换脑子。 目前内测系统的华为应用市场,各种顶级APP陆续都放出来beta版本了,大体上都完成了主流程的开发。欣欣向荣的气息。 学习思路 关于学习HarmonyOS的问题…...
Spring中事件监听器
实现ApplicationListener接口 Configuration public class A48 {public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(A48.class);context.getBean(MyService.class).doBusiness();context.close()…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...

02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...