项目地址:https://github.com/wannengdek/spring-boot-seckill
如果项目对您有所帮助,麻烦帮忙点亮小⭐⭐
登录业务
1、数据库设计
DROP TABLE IF EXISTS `miaosha_user`;
CREATE TABLE `miaosha_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户id,手机号',
`nickname` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL COMMENT 'MD5(mD5(pas明文+固定salt)+salt)',
`salt` varchar(255) DEFAULT NULL,
`head` varchar(255) DEFAULT NULL COMMENT '头像',
`register_date` datetime DEFAULT NULL COMMENT '注册时间',
`last_login_date` datetime DEFAULT NULL,
`login_count` varchar(255) DEFAULT NULL COMMENT '登录次数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of miaosha_user
-- ----------------------------
INSERT INTO `miaosha_user` VALUES ('18912341234', '18912341234', 'b7797cce01b4b131b433b6acf4add449', '1a2b3c4d', null, '2019-08-14 16:13:22', '2019-08-14 16:13:26', '1');
创建好之后:
2、使用两次md5进行加密
为了防止单次md5被解密,特使用多次md5加密。
md5 依赖引入
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
构建md5加密
从前端得到的密码进行第一次加密,传输到服务端,然后再加密,将两次加密之后的密码存储到数据库中。
判断用户是否可以登录时,将数据库中的密码取出,逆向解密之后与前端传的密码做比较,以此来判断。
package spring.mooc.seckill.util;
import org.apache.commons.codec.digest.DigestUtils;
public class MD5Util {
/**
* 第一次MD5
* @param src
* @return
*/
public static String md5(String src) {
return DigestUtils.md5Hex(src);
}
private static final String salt = "1a2b3c4d";
/**
* 用户输入密码转换为 服务端密码
* @param inputPass
* @return
*/
public static String inputPassToFormPass(String inputPass) {
String str = ""+salt.charAt(0)+salt.charAt(2) + inputPass +salt.charAt(5) + salt.charAt(4);
System.out.println(str);
return md5(str);
}
/**
* 服务端密码转换为 数据库密码
* @param formPass
* @param salt
* @return
*/
public static String formPassToDBPass(String formPass, String salt) {
String str = ""+salt.charAt(0)+salt.charAt(2) + formPass +salt.charAt(5) + salt.charAt(4);
return md5(str);
}
public static String inputPassToDbPass(String inputPass, String saltDB) {
String formPass = inputPassToFormPass(inputPass);
String dbPass = formPassToDBPass(formPass, saltDB);
return dbPass;
}
前端验证通过之后传输到后端
<script>
function login(){
$("#loginForm").validate({
submitHandler:function(form){
doLogin();
// 验证通过回调函数
}
});
}
function doLogin(){
g_showLoading();
var inputPass = $("#password").val();
var salt = g_passsword_salt;
var str = ""+salt.charAt(0)+salt.charAt(2) + inputPass +salt.charAt(5) + salt.charAt(4);
var password = md5(str);
$.ajax({
url: "/login/do_login",
type: "POST",
data:{
mobile:$("#mobile").val(),
password: password
},
success:function(data){
layer.closeAll();
console.log(data);
if(data.code == 0){
layer.msg("success");
window.location.href="/goods/to_list";
}else{
layer.msg(data.msg);
}
},
error:function(){
layer.closeAll();
}
});
}
</script>
Controller 控制登录流程
@RequestMapping("/do_login")
@ResponseBody
public Result<Boolean> doLogin(LoginVo loginVo) {
log.info(loginVo.toString());
String passInput = loginVo.getPassword();
String mobile =loginVo.getMobile();
if (StringUtils.isEmpty(passInput))
{
return Result.error(CodeMsg.PASSWORD_EMPTY);
}
if (StringUtils.isEmpty(mobile))
{
return Result.error(CodeMsg.MOBILE_EMPTY);
}
if (!ValidatorUtil.isMobile(mobile))
{
return Result.error(CodeMsg.MOBILE_ERROR);
}
boolean login = miaoshaUserService.login(loginVo);
if (login)
{
System.out.println("success");
return Result.success(true);
}
else
{
return Result.error(CodeMsg.MOBILE_ERROR);
}
}
LoginVo 是一个用来封装用户名和密码的中间类
service 中的login 方法
public boolean login(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.equals(dbPass)) {
throw new GlobalException(CodeMsg.PASSWORD_ERROR);
}
return true;
}
3、当前效果: