祈安云盘项目系列文章:
【启动】一个云盘项目——Java后端
【祈安云盘】系统设计+目录结构+用户数据库设计
【祈安云盘】图片验证码+邮箱验证码
一、注册
1.controller层
2.service层
serviceImpl,首先判断邮箱账号是否存在,然后输入昵称,要求昵称唯一,然后校验验证码是否输入正确,最后在数据库存储相关信息。
(1)checkcode校验邮箱验证码
(2)将密码保存为MD5哈希
二、登录
用session实现登录
controller:
serviceImpl:
这里涉及到了fileInfoService,先暂时不实现这个。
三、找回密码
controller:
serviceImpl:
四、校验登录
我们在做一些操作(如上传文件)之前需要检验是否是登录状态,流程如下图:
在GlobalOperationAspect中完成校验登录:
qq登录
配置文件
controller层:
回调:
拿到地址,扫码授权,就可以获得回调code,通过回调code进行用户登录
其他的找回密码、上传头像等操作比较简单,就不再赘述了。
优化
1、基于Resdis实现登录
首先回顾一下基于Session实现的登录步骤:
对于单体的项目来说,基于session实现校验登录是可行的,但是对于多台tomcat不共享session存储空间,当请求切换到不同的tomcat服务时会导致数据丢失的问题。
那么session的替代方案应该满足三个条件:
数据共享:多台tomcat共享存储
内存存储:session是基于内存存储的,效率高
key-value结构
那么答案就是:Redis
首先,注册时以邮箱为key,验证码为value保存到Redis中,这样验证校验码时以邮箱为key读取验证码即可。
注册/登录时以随机token为key、昵称为value保存到Redis。
2、密码加密
最常用的密码加密方法是MD5,首先来简单介绍一下MD5算法。
MD5英文全称为message-digest algorithm 5(信息摘要算法5),以任意长度的数据为输入,产生一个128位的哈希值,通常表示为32位的十六进制数字。MD5算法的主要特点包括:
不可逆性:MD5函数是不可逆的,从哈希值无法恢复原始数据
固定输出长度:无论输入数据的长度如何,MD5算法总是产生一个128位的固定长度哈希值
碰撞抵抗性:在合理的时间内,难以找到两个具有相同的MD5哈希值的不同的输入
但是如果只使用MD5加密是不安全的,可以被彩虹表破解。彩虹表是一个用于加密散列函数逆运算的预先计算好的表,为破解密码的散列值而准备。简单来说,彩虹表就是一个很大的,用于存放穷举对应值的数据表。这样的话,获取密文就可以直接插到原始密码。
那么为了增加安全性,可以选择加盐。盐(Salt)在密码学中,是指通过在密码任意固定位置插入特定的字符串,让哈希后的结果和使用原始密码的哈希结果不相符,这种过程称之为“加盐”。但加盐只是增加了破解难度,不代表无法破解。
安全性更高的一种方案是使用 密钥派生算法(Key Derivation Function,简称 KDF,也称为密码哈希算法)。相比其他加密哈希算法,KDF 的计算速度很慢,而且从设计上就使其计算速度难以提升,所以 KDF 也被称为 慢哈希算法 。但这个慢相比于其带来的安全性来说是可以接受的,毕竟主要也是在登录时执行一次。
对于绝大多数项目来说,比较适合的一种KDF算法是Bcrypt,一种基于 Blowfish 加密算法的密码哈希算法。Bcrypt 采用了 salt(盐) 和 cost(成本) 两种机制,它可以有效地防止彩虹表攻击和暴力破解攻击,从而保证密码的安全性。加 salt 可以防止彩虹表攻击,也就是说,使用 Bcrypt 加密密码时已经包含了一个随机加盐的过程,不需要额外加盐了。cost 又称为工作因子,定义了哈希计算的复杂度。成本越高,计算所需的时间和资源就越多,这使得暴力破解攻击变得更加困难。实际项目中,可以根据系统的性能和安全需求调整 cost。