技术分享
中传放心传
00 分钟
2022-8-14
2023-6-23
type
status
date
slug
summary
tags
category
icon
password
Property
Jun 23, 2023 11:48 AM

☁️CUC-cloud-disk-upload-management-system

一个基于Vue和springboot+mybatisplus实现的文件云盘管理系统

演示视频

项目展示地址

💭在线地址http://119.23.64.32/
🎆项目域名http://www.cucinstall.cn/(目前还在备案中。。。。。)

使用手册

请参照中传放心传官方文档

源码地址

GitHub - Xuyan-cmd/CUC-cloud-disk-upload-management-system: 一个基于Vue和springboot+mybatisplus实现的文件云盘管理系统
基于网页的用户注册与登录系统(60分) 使用https绑定证书到域名而非IP地址 【 PKI X.509 】 允许用户注册到系统 用户名的合法字符集范围:中文、英文字母、数字 类似:-、_、.等合法字符集范围之外的字符不允许使用 用户口令长度限制在36个字符之内 对用户输入的口令进行强度校验,禁止使用弱口令 使用合法用户名和口令登录系统 禁止使用明文存储用户口令 【PBKDF2、散列算法、慢速散列、针对散列算法(如MD5、SHA1等)的攻击方法】 存储的口令即使被公开,也无法还原/解码出原始明文口令 (可选)安全的忘记口令 / 找回密码功能 (可选)微信/微博/支付宝的OAuth授权登录 / 注册绑定 基于网页的文件上传加密与数字签名系统(20分) 已完成《基于网页的用户注册与登录系统》所有要求 限制文件大小:小于 10MB 限制文件类型:office文档、常见图片类型 匿名用户禁止上传文件 对文件进行对称加密存储到文件系统,禁止明文存储文件 【 对称加密 密钥管理(如何安全存储对称加密密钥) 对称加密密文的PADDING问题 】 系统对加密后文件进行数字签名 【 数字签名(多种签名工作模式差异) 】 (可选)文件秒传:服务器上已有的文件,客户端可以不必再重复上传了 基于网页的加密文件下载与解密(20分) 已完成《基于网页的文件上传加密与数字签名系统》所有要求 提供匿名用户加密后文件和关联的数字签名文件的下载 客户端对下载后的文件进行数字签名验证 【 非对称(公钥)加密 数字签名 】 客户端对下载后的文件可以解密还原到原始文件 【 对称解密 密钥管理
GitHub - Xuyan-cmd/CUC-cloud-disk-upload-management-system: 一个基于Vue和springboot+mybatisplus实现的文件云盘管理系统

任务清单

第一阶段(7.12-7.17(周日))
  • 基于网页的用户注册与登录系统(60分)
    • 使用https绑定证书到域名而非IP地址 【 PKI X.509 】
      允许用户注册到系统
      • 用户名的合法字符集范围:中文、英文字母、数字
        • 类似:-、_、.等合法字符集范围之外的字符不允许使用
      • 用户口令长度限制在36个字符之内
      禁止使用明文存储用户口令 【PBKDF2、散列算法、慢速散列、针对散列算法(如MD5、SHA1等)的攻击方法】
      • 存储的口令即使被公开,也无法还原/解码出原始明文口令
      • 对用户输入的口令进行强度校验,禁止使用弱口令
      使用合法用户名和口令登录系统
      (可选)安全的忘记口令 / 找回密码功能
      (可选)微信/微博/支付宝的OAuth授权登录 / 注册绑定
      (可选)双因素认证
      • OTP: Google Authenticator
      • Email
      • SMS
      • 扫码登录
第二阶段(7.18-7.24)
  • 基于网页的文件上传加密与数字签名系统(20分)
    • 已完成《基于网页的用户注册与登录系统》所有要求
      限制文件大小:小于 10MB
      限制文件类型:office文档、常见图片类型
      匿名用户禁止上传文件
      对文件进行对称加密存储到文件系统,禁止明文存储文件 【 对称加密 密钥管理(如何安全存储对称加密密钥) 对称加密密文的PADDING问题 】
      系统对加密后文件进行数字签名 【 数字签名(多种签名工作模式差异) 】
      (可选)文件秒传:服务器上已有的文件,客户端可以不必再重复上传了
第三阶段(7.25-8.5)
  • 基于网页的加密文件下载与解密(20分)
    • 已完成《基于网页的文件上传加密与数字签名系统》所有要求
      提供匿名用户加密后文件和关联的数字签名文件的下载
      • 客户端对下载后的文件进行数字签名验证 【 非对称(公钥)加密 数字签名 】
      • 客户端对下载后的文件可以解密还原到原始文件 【 对称解密 密钥管理 】
      提供已登录用户解密后文件下载
      下载URL设置有效期(限制时间或限制下载次数),过期后禁止访问 【 数字签名 消息认证码 Hash Extension Length Attack Hash算法与HMAC算法的区别与联系 】
      提供静态文件的散列值下载,供下载文件完成后本地校验文件完整性 【 散列算法 】

开发日志

前端开发日志
  • 2022.7.11 创建项目仓库,设置工作区
  • 2022.7.12 创建前端Vue项目,并进行初始化
总文件名称Front-end-project
notion image
完成进度:配置对应的登录初始界面,设置基本路由,前端总体开发采用Vue+Element ui
问题反馈:
  • vue中路由的配置与使用
引入路由:
路由实例化:
定义路由中的内容:
将路由注入Vue对象:
Element UI技术文档:Element UI技术文档

2022.7.13 编写首页登陆界面,确定接口传递数据方式

更新内容:
  • 编写login.vue界面,确定用户向后端传递口令和账号信息用ajax传递
  • 主页面初步呈现效果如下:
notion image
notion image
  • 修改页面的路由配置,初步建立文件上传、文件删除的页面跳转规则
  • 修复登陆跳转bug
  • 登录成功能够进入初始页面
notion image

2022.7.14进行前端文件管理页面优化,添加了多个小组件显示效果,优化了对应的界面显示

  • 编写音乐播放组件MusicPlayer.vue,显示效果如下:
notion image
  • 编写视频播放组件以及上传进度条组件,分别为VideoPlayer.vueProgressDialog.vue
  • 组件使用规范如下:
  • 编写登录后的系统主页index.vue
  • 系统主页预期实现效果如下:
notion image
  • 编写相册页Albums.vue
notion image
  • 编写收藏夹页面Collectes.vue
notion image
  • 页面跳转功能实现:
  • 编写用户管理小组件UserInfoCard.vue,效果如下:
notion image

2022.7.16实现登录注册界面功能,实现文件上传下载

更新内容:
  • 编写后端数据接口,实现用户登录、注册口令存储到本地数据库,数据库编写采用SQLite
  • 实现文件、图片格式上传存储
notion image
notion image
  • 对用户的注册信息口令进行存储
在登录注册主页面,将用户信息存储到对应的接口所对应的数据库中
notion image
问题反馈
对于如何加密用户的存储信息和加解密,以及实现多种方式注册信息查阅了相关资料
  • 此处查阅了Vue框架对于登陆界面的规则文档,此出提供了一个思路,通过引入crypto JS去实现对于信息的存储
    • 示例如下:
    • HTML code
    • js code

2022.7.17优化前端功能页面,修复文件下载、排序、显示问题

更新内容:
  • 修复由于接口回调过程中出现下载中断,导致的文件不能下载问题。
  • 新增根据文件大小进行排序功能。
notion image

2022.7.19修复文件管理页面在从数据库调取数据中出现的文件不能显示和打开,新增文件列表显示功能

更新内容:
  • 在vue前端调取文件拉去接口中赋予每个文件一个用户id用以区分不同身份用户
  • 成功实现不同身份用户上传数据不会出现重复

2022.7.21修复前端传递数据到后端中由于文件大小导致的TTL过长而请求中断的问题

方法解析:
原因:
  1. 服务器配置:例如在PHP中默认的文件上传大小为8M【post_max_size = 8m】,若你在一个请求体中放入8M以上的内容时,便会出现异常
  1. 请求超时:当你设置了接口的超时时间为10s,那么上传大文件时,一个接口响应时间超过10s,那么便会被Faild掉。
  1. 网络波动:这个就属于不可控因素,也是较常见的问题。
分片上传
  • 创建切片,循环分解文件即可
  • 循环创建切片,既然咱们做的是多文件,所以这里就有循环去处理,依次创建文件切片,及切片的上传。
  • 上传切片,这个里需要考虑的问题较多,也算是核心吧,uploadChunks方法只负责构造传递给后端的数据,核心上传功能放到sendRequest方法中
  • sendReques。上传这是最重要的地方,也是容易失败的地方,假设有10个分片,那我们若是直接发10个请求的话,很容易达到浏览器的瓶颈,所以需要对请求进行并发处理。
    • 并发处理:这里我使用for循环控制并发的初始并发数,然后在 handler 函数里调用自己,这样就控制了并发。在handler中,通过数组API.shift模拟队列的效果,来上传切片。
    • 重试: retryArr 数组存储每个切片文件请求的重试次数,做累加。比如[1,0,2],就是第0个文件切片报错1次,第2个报错2次。为保证能与文件做对应,const index = formInfo.index; 我们直接从数据中拿之前定义好的index。 若失败后,将失败的请求重新加入队列即可。
  • 切片的上传进度,通过axios的onUploadProgress事件,结合createProgresshandler方法进行维护
  • 因此此处使用切片进行项目对于文件的上传和拉取:

2022.7.22修改文件存储方式,改用直接存储到阿里的OSS中

此前文件的上传和拉去均在本地数据库实现,为了能够更好的实现文件的存储管理,因此我开通了阿里的OSS对象存储服务,直接将文件统一上传到线上。
  • 将文件上传接口和拉去接口联通到开通的OSS上(涉及到保密机制,故此处不给出全部代码)
notion image
  • 写一个公用的ali-oss.js
  • 调用
  • 使用Element-UI的 Upload 组件的自定义方法http-request上传,覆盖默认的。
notion image

2022.7.24优化文件管理功能增加文件移动、重命名、属性查看功能

更新内容:
  • 新增文件拖拽移动功能,修复文件移动时造成的获取数据失败Bug
notion image
  • 调用ali-oss的数据接口,获取已上传的文件属性内容
    • 用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处。
      $option 是用来获取data外面的数据和方法。
      this.$options 即可以获取自定义属性,也可以增加自定义属性,而且,获取自定义属性的方法有两种。
      this.mydata = this.$options['myoption'] this.mydata1 = this.$options.myoption
notion image

2022.7.26新增文件查找功能

这里涉及到在vue中定义和调用函数,需要用到关键字methods,然后便可以在里面定义函数了。
这里关键点:
  • document.getElementById('open').files[0].path,这里获取文件路径的方法是获取文件类元素的数组,然后通过path关键字获取文件的绝对路径。
notion image
notion image

2022.7.28用户登录界面对用户口令进行限制和密码强度检测

用户名和口令
限用户输入一些非常容易被破解的口令。如什么qwert,123456,password之类,就像twitter限制用户的口令一样做一个口令的黑名单。另外,可以限制用户口令的长度,是否有大小写,是否有数字,可以用程序做一下校验。当然,这可能会让用户感到很不爽,所以,现在很多网站都提供了UX让用户知道他的口令强度是什么样的这样可以让用户有一个选择,目的就是告诉用户——要想安全,先把口令设得好一点。
基于这种想法,我对于用户在注册时的口令进行了密码强度检验,对密码长度和复杂程度都进行了一个展示,通过下方出现的颜色字条来标识密码强度
例:
  • 当密码为:123456789时,强度颜色条为红色
notion image
  • 当密码为:xu123456789时,强度颜色条为蓝色
notion image
  • 当密码为xu123456789-.(此处设定-、_、.等合法字符集范围之外的字符不允许使用)
notion image
此外,在存储用户口令数据到数据库时,采用了md5方式进行了加密
这里有两种方式可供参考
直接在需要使用md5加密的页面引入
然后将想要加密的数据放入
全局挂载,将js-md5添加到vue原型链上
然后将想要加密的数据放入
在项目中,想要将用户注册的密码由明文转为密文,在传递参数时可以先将密码md5加密后,再传给后端接口,放到数据库中。这样数据库中密码存放的就是密文而不是明文了。
在用户注册成功后进行登录时,因为js-md5加密是不可逆的,除非进行暴力破解,例如枚举,所以不需要将数据库中存储的密码密文再转为明文,而是在传递登录密码时将用户输入的密码进行md5加密处理,再与之对比验证。
notion image

2022.7.30新增文件加密和散列值获取功能界面

更新内容:
  • 新增文件加密功能按钮选项,并与后端接口联通,成功实现数据加密
notion image
  • 计算文件的散列值,并进行逐比特对比,判断文件是否遭到篡改
1.先下载
2.在使用的vue页面引入和声明方法
3.使用方法:
4.终止md5计算方法(大文件计算很费时 ):
5.代码可以直接复制使用:
notion image

2022.7.31修复界面显示出错、文件数据获取等并发性错误

后端开发日志

2022.7.11 创建项目仓库,设置工作区

2022.7.12创建项目初始化框架,生成demo文件

notion image
  • 项目结构介绍
notion image
如上图所示,Spring Boot 项目结构如下
  • src/main/java 主程序入口和项目开发
  • src/resources 项目配置文件
  • src/test/java 测试程序
此外,建议在包名下分别新建 controller、domain、service、mapper,这些分别表示
  • controller:页面访问控制,也就是 api,
  • domain:主要用于实体类和数据访问层(mapper)
  • service:业务处理
  • SpringBootProjctApplication.java:主程序,创建项目时会自动创建,一般为项目名称+Application.java
最后,启动 SpringBootProjctApplication 主程序。这样就完成 Java 项目配置了。
注:controller、domain、service、mapper 包,需要放在 SpringBootProjctApplication.java 主程序同包名或放在主程序下,否则主程序会扫描不到,导致报错。
  • Web 模块
在配置之前,先说明一下 pom.xml 文件。此文件包含 Spring Boot 版本、项目基本信息、第三方 Jar 包 Maven 引用。
所以,我们引用 Web 模块时,需要在 pom.xml 的 dependencies 添加以下代码:
其中,pom.xml 有两个默认的 模块
  • spring-boot-starter:Spring Boot的核心启动器,包含了自动配置、日志和YAML。
  • spring-boot-starter-test:支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块。
编写 Controller api 内容
在 controller 包下新建 TestController.java,内容如下:
这时,我们启动主程序,在浏览器输入localhost:8080/test,就可以看到返回的结果。是不是很简单,只需要很少的配置,就可以创建一个 Java Web 项目了。
notion image

2022.7.15建立数据库,设置好对应的表单名称、数据属性

  • 建立数据库的Sql
    • 初始化数据库内容:
    notion image

    2022.7.16编写对应的数据接口,测试接口功能是否正常

    2022.7.19修复文件上传接口Bug,新增文件状态值检验

    2022.7.20实现对用户口令进行加密和强度检验

    消息摘要(数据的指纹)
    定义
    • 对不固定的消息(字符串,一段文本,一个文件),通过一种特定的算法,得到一个固定长度的文本,固定长度的文本叫做消息摘要
    • 比如我是程序员经过特定的算法之后,得到了消息摘要为:adaf02515dfds7885csdfcdsc
    作用
    • 数据完整性的检验技术,我们将文本转换为消息摘要,然后比较消息摘要的值是否相等,如果相等那么表示两种文本相同
    特性
    • 不可逆的,不能从消息摘要再得到原来的文本
    特定的算法
    1. MD5
    1. SHA
    实现步骤
    • 添加依赖jar包
      • commons-codec
    • 测试MD5Hex
      • 得到的是32位的16进制的字符串
    密码加密
    • 避免在数据库中明文保存密码,通过消息摘要技术对密码进行加密
    明文
    • 没有加密的文字(字符串),能看懂的文字
    密文
    • 经过加密后的文字(字符串),看不出来明文的意思
    加盐处理 salt
    • 为了提高密码的安全性
    • 就是在用户的密码之后随便添加一个字符串,然后连接在一起生成摘要,那么即使获取摘要,也不会被破解。
    实现
    • 涉及到密码: 登录,注册,修改密码
    • 创建一个MD5Password工具类,用于加密密码
    • 在注册的时候对输入的密码进行加密存储到数据库中
    • 在登录的时候,将用户输入的密码进行加密获取到加密之后的密码,然后和数据库中的密码比较
    • 在修改中,将旧密码加密后和数据库中的密码比较,并且将新密码加密更新到数据库中

    2022.7.22新增文件接口参数加密,调整文件存储状态的返回值

    我们先来定义一个加密工具类备用,加密这块有多种方案可以选择,对称加密、非对称加密,其中对称加密又可以使用 AES、DES、3DES 等不同算法,这里我们使用 Java 自带的 Cipher 来实现对称加密,使用 AES 算法:
    这个工具类比较简单,不需要多解释。需要说明的是,加密后的数据可能不具备可读性,因此我们一般需要对加密后的数据再使用 Base64 算法进行编码,获取可读字符串。换言之,上面的 AES 加密方法的返回值是一个 Base64 编码之后的字符串,AES 解密方法的参数也是一个 Base64 编码之后的字符串,先对该字符串进行解码,然后再解密。
    接下来我们定义两个注解 @Decrypt 和 @Encrypt
    这两个注解就是两个标记,在以后使用的过程中,哪个接口方法添加了 @Encrypt 注解就对哪个接口的数据加密返回,哪个接口/参数添加了 @Decrypt 注解就对哪个接口/参数进行解密。这个定义也比较简单,没啥好说的,需要注意的是 @Decrypt 比 @Encrypt 多了一个使用场景就是 @Decrypt 可以用在参数上。
    考虑到用户可能会自己配置加密的 key,因此我们再来定义一个 EncryptProperties 类来读取用户配置的 key:
    另外还有一点需要注意,ResponseBodyAdvice 在你使用了 @ResponseBody 注解的时候才会生效,RequestBodyAdvice 在你使用了 @RequestBody 注解的时候才会生效,换言之,前后端都是 JSON 交互的时候,这两个才有用。不过一般来说接口加解密的场景也都是前后端分离的时候才可能有的事。
    先来看接口加密:
    我们自定义 EncryptResponse 类实现 ResponseBodyAdvice接口,泛型表示接口的返回类型,这里一共要实现两个方法:
    1. supports:这个方法用来判断什么样的接口需要加密,参数 returnType 表示返回类型,我们这里的判断逻辑就是方法是否含有 @Encrypt 注解,如果有,表示该接口需要加密处理,如果没有,表示该接口不需要加密处理。
    1. beforeBodyWrite:这个方法会在数据响应之前执行,也就是我们先对响应数据进行二次处理,处理完成后,才会转成 json 返回。我们这里的处理方式很简单,RespBean 中的 status 是状态码就不用加密了,另外两个字段重新加密后重新设置值即可。
    1. 另外需要注意,自定义的 ResponseBodyAdvice 需要用 @ControllerAdvice 注解来标记。
    再来看接口解密:
    1. supports:该方法用来判断哪些接口需要处理接口解密,我们这里的判断逻辑是方法上或者参数上含有 @Decrypt 注解的接口,处理解密问题。
    1. beforeBodyRead:这个方法会在参数转换成具体的对象之前执行,我们先从流中加载到数据,然后对数据进行解密,解密完成后再重新构造 HttpInputMessage 对象返回。
    接下来,我们再来定义一个自动化配置类,如下:
    最后,resources 目录下定义 META-INF,然后再定义 spring.factories 文件,内容如下:

    2022.7.26创建文件删除、修改接口并实现功能,修复用户登录接口由于用户ID重复造成的状态回显异常

    • 文件删除、修改接口
    • 用户登录接口查询检查

    2022.7.30修改文件删除中的实现逻辑,使得在OSS的源文件能够备份,而前端不再拉取文件数据

    • 为了能够对用户的上传文件进行身份验证,故不对数据库的源文件进行删除,而是在后端返回的data字段中不返回对应url值,即前端不再拉取对应的文件数据

    2022.7.31实现对文件按大小、时间日期排序,优化显示效果

     

    评论
    • Twikoo