秒杀系统的项目主要是为了应对高并发的场景,所以在项目主要包含有几个关键的模块:商品模块、
用户登录模块、秒杀模块、秒杀安全优化等等。
1. 登录模块
主要包括了登录密码的加密和分布式session
1.1 登陆密码加密
用户登录的时候,登录信息由前端传递到后端是通过http协议进行传输的,由于http协议是明文传输的。所有的登录信息都在其body里面,所以将用户的登录密码进行明文传输安全性较低。所以在传输之前,我们在前端需要对password进行加密,通过MD5进行对称加密。
整个加密过程分为两次MD5加密:
(1)客户端:PASS = MD5(明文)
(2)服务端:PASS = MD5(用户输入+随机salt)
MD5加密的原理:MD5 (Message -digest algorithm 5)就是信息摘要的一种实现,它可以从任意长度的明文字符串生成128位的哈希值,也就是32位的16进制。
第一次 (在前端加密,客户端):密码加密是明文密码生成md5用于传输,目的,由于http是明文传输,当输入密码若直接发送服务端验证,此时被截取将直接获取到明文密码,获取用户信息。加盐值是为了混淆密码,加盐就是向明文中加入随机数,然后在生成MD5,这样一来即使明文相同,每次生成的MD5码也不同。
第二次:在服务端再次加密,当获取到前端发送来的密码后。通过MD5(密码+随机盐值)再次生成密码后存入数据库。防止数据库被盗的情况下,通过md5反查,查获用户密码。方法是盐值会在用户注册的时候随机生成,并存在数据库中,这个时候就会获取到。
第二次的目的:
如果只进行一次MD5加密,此时数据库泄漏,通过解析前端js文件,就知道md5加密的过程,就知道此时用户的密码。
但是此时我们要是在后端加入随机盐值和传输密码的md5组合,黑客是无法知道通过后端密码加密过程的,从而无法知道密码。虽然黑客能够获取到数据库加密后的密码和盐值,但是不知道加密过程,就很难破解出来。
实现过程:
- 通过前端传来的账号mobile,查询数据库是否存在该条记录
- 获取到该用户的盐值salt和前端传递的password,在后台进行第二次加密,加密的方式写在后端
- 比较第二次加密后的密码和数据库中密码是否一致
public String login(HttpServletResponse response, LoginVo loginVo) {
if(loginVo == null) {
throw new GlobalException(CodeMsg.SERVER_ERROR);
}
String mobile = loginVo.getMobile();
String formPass = loginVo.getPassword();
//判断手机号是否存在
MiaoshaUser user = getById(Long.parseLong(mobile));
if(user == null) {
throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
}
//验证密码
String dbPass = user.getPassword();
String saltDB = user.getSalt();
String calcPass = MD5Util.formPassToDBPass(formPass, saltDB);
if(!calcPass.