大学老师一般都是把真实密码存放到数据库中,但那只是演示,并非企业开发是这样做的。
数据库里面存的是做了两次MD5的用户密码 与其对应的salt值
现在我们登录的时候,要去取得数据库里面对应用户的密码和salt值,然后后台接收了前端做了一次MD5的密码formPass,然后将这个formPass去和数据库里面的salt一起再做一次MD5,然后检测是否与数据库里面存的那个密码一致。
MD5也不是绝对安全的,但是我们可以使得破解的难度指数级增长。md5是不可逆的,不能反向解密的,网上所谓的“解密”都是把“加密”结果存储到数据库再比对的只能暴力破解,即有一个字典,从字典中读取一条记录,将密码用加salt盐值做MD5来对比数据库里面的值是否相
先弄清楚原理再来实现代码
两次MD5:
@Getter @Setter public class MiaoshaUser { private Long id; private String nickname; private String pwd; private String salt; private String head; private Date registerDate; private Date lastLoginDate; private Integer loginCount;
@Mapper public interface MiaoshaUserDao { @Select("select * from miaosha_user where id=#{id}") //这里#{id}通过后面参数来为其赋值 public MiaoshaUser getById(@Param("id")long id); //绑定 //绑定在对象上面了----@Param("id")long id,@Param("pwd")long pwd 效果一致 @Update("update miaosha_user set pwd=#{pwd} where id=#{id}") public void update(MiaoshaUser toupdateuser); //public boolean update(@Param("id")long id); //绑定 }
@Service public class MiaoshaUserService { public static final String COOKIE1_NAME_TOKEN="token"; @Autowired MiaoshaUserDao miaoshaUserDao; @Autowired RedisService redisService; /** * 根据id取得对象,先去缓存中取 * @param id * @return */ public MiaoshaUser getById(long id) { //1.取缓存 ---先根据id来取得缓存 MiaoshaUser user=redisService.get(MiaoshaUserKey.getById, ""+id, MiaoshaUser.class); //能再缓存中拿到 if(user!=null) { return user; } //2.缓存中拿不到,那么就去取数据库 user=miaoshaUserDao.getById(id); //3.设置缓存 if(user!=null) { redisService.set(MiaoshaUserKey.getById, ""+id, user); } return user; } }
@RequestMapping("/login") @Controller public class LoginController{ @Autowired UserService userService; @Autowired RedisService redisService; @Autowired MiaoshaUserService miaoshaUserService; //slf4j private static Logger log=(Logger) LoggerFactory.getLogger(Logger.class); @RequestMapping("/to_login") public String toLogin() { return "login";// 返回页面login } @RequestMapping("/do_login") // 作为异步操作 @ResponseBody public CodeMsg doLogin(LoginVo loginVo) {// 0代表成功 // log.info(loginVo.toString()); if (loginVo == null) { return CodeMsg.SERVER_ERROR; } // 验证 String formPass = loginVo.getPassword(); String mobile = loginVo.getMobile(); // 验证用户 MiaoshaUser user = miaoshaUserService.getById(Long.parseLong(mobile)); if (user == null) { return CodeMsg.MOBILE_NOTEXIST; } // 验证密码 String dbPass = user.getPwd(); String dbSalt = user.getSalt(); System.out.println("dbPass:" + dbPass + " dbSalt:" + dbSalt); //现在我们登录的时候,要去取得数据库里面对应用户的密码和salt值,然后后台接收了前端做了一次MD5的密码formPass,然后将这个formPass去和数据库里面的salt一起再做一次MD5,然后检测是否与数据库里面存的那个密码一致。 // 验证密码,计算二次MD5出来的pass是否与数据库一致 String tmppass = MD5Util.formPassToDBPass(formPass, dbSalt); System.out.println("formPass:" + formPass); System.out.println("tmppass:" + tmppass); if (!tmppass.equals(dbPass)) { return CodeMsg.PASSWORD_ERROR; } return CodeMsg.SUCCESS; } }
引入bootstrap 引入相关的js和css
核心代码: (最下面有完整的代码)
var pass=$("#password").val(); //pass='111111'; //固定salt var salt='1a2b3c4d'; var str=""+salt.charAt(0)+salt.charAt(2)+pass+salt.charAt(5)+salt.charAt(4); var password=md5(str); //alert(salt); //alert(pass); //alert(password); //与后台Md5规则一致 //var str=""+salt.charAt(0)+salt.charAt(2)+formPass+salt.charAt(5)+salt.charAt(4); $.ajax({ url:"/login/do_login", type:"POST", data:{ mobile:$("#phone").val(), password:password, }, success:function(data){ if(data.code==0){ alert("success"); //成功后跳转 window.location.href="/goods/to_list"; }else{ alert(data.msg); } }, error:function(data){ alert("error"); //alert(data.msg); } });
<!DOCTYPE html> <!-- 使用thymeleaf,配置相应的 --> <html xmlns:th="http://www.thymeleaf.org"> <!-- th!!! 命名空间使用 --> <head> <meta charset="UTF-8"/><!--<meta charset="UTF-8" /> thymeleaf模板引擎默认是Template modes:HTML5解析的,所以解析比较严格。 --> <title>登录</title> <!-- thymeleaf引入静态资源的方式,@加大括弧 "/" 代表static路径--> <!-- jquery --> <!-- <script type="text/javascript" th:src="@{/js/jequery.min.js}"></script> --> <script type="text/javascript" th:src="@{/jquery-validation/lib/jquery-1.11.1.js}"></script> <!-- bootstrap --> <!-- <link type="text/css" rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}"/> --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"/> <script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script> <!--jquery-validator --> <script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script> <!-- <script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.js}"></script> --> <script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script> <!-- layer --> <script type="text/javascript" th:src="@{/layer/layer.js}"></script> <!-- md5.js --> <script type="text/javascript" th:src="@{/js/md5.min.js}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-sm-8 offset-sm-2"> <div class="border-bottom mb-4 mt-4 pb-2"> </div> <div class="card"> <div class="card-header"> <h6 class="card-text">Simple Form</h6><!--</h3> --> </div> <div class="card-body"> <form id="signupForm" method="post" class="form-horizontal" ><!-- action="" --> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="phone">Phone</label> <div class="col-sm-6"> <input type="text" class="form-control" id="phone" name="phone" placeholder="phone" /> </div> </div> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="username">Username</label> <div class="col-sm-6"> <input type="text" class="form-control" id="username" name="username" placeholder="Username" /> </div> </div> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="email">Email</label> <div class="col-sm-6"> <input type="text" class="form-control" id="email" name="email" placeholder="Email" /> </div> </div> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="password">Password</label> <div class="col-sm-6"> <input type="password" class="form-control" id="password" name="password" placeholder="Password" /> </div> </div> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="confirm_password">Confirm password</label> <div class="col-sm-6"> <input type="password" class="form-control" id="confirm_password" name="confirm_password" placeholder="Confirm password" /> </div> </div> <div class="form-group row"> <div class="col-sm-6 offset-sm-4"> <div class="form-check"> <input type="checkbox" id="agree" name="agree" value="agree" class="form-check-input"/> <label class="form-check-label">Please agree to our policy</label> </div> </div> </div> <div class="form-group row"> <div class="col-sm-9 offset-sm-4"> <button type="submit" class="btn btn-primary" name="signup" value="Sign up">Sign up</button> </div> </div> </form> </div> </div> </div> </div> </div> <script type="text/javascript"> $.validator.setDefaults( { submitHandler: function () { var pass=$("#password").val(); //pass='111111'; var salt='1a2b3c4d'; var str=""+salt.charAt(0)+salt.charAt(2)+pass+salt.charAt(5)+salt.charAt(4); var password=md5(str); //alert(salt); //alert(pass); //alert(password); //与后台Md5规则一致 //var str=""+salt.charAt(0)+salt.charAt(2)+formPass+salt.charAt(5)+salt.charAt(4); $.ajax({ url:"/login/do_login", type:"POST", data:{ mobile:$("#phone").val(), password:password, }, success:function(data){ if(data.code==0){ alert("success"); //成功后跳转 window.location.href="/goods/to_list"; }else{ alert(data.msg); } }, error:function(data){ alert("error"); //alert(data.msg); } }); //alert( "submitted!" ); } } ); $( document ).ready( function () { $( "#signupForm" ).validate( { rules: { firstname: "required", lastname: "required", username: { required: true, minlength: 2 }, password: { required: true, minlength: 5 }, confirm_password: { required: true, minlength: 5, equalTo: "#password" }, email: { required: true, email: true }, agree: "required" }, messages: { firstname: "Please enter your firstname", lastname: "Please enter your lastname", username: { required: "Please enter a username", minlength: "Your username must consist of at least 2 characters" }, password: { required: "Please provide a password", minlength: "Your password must be at least 5 characters long" }, confirm_password: { required: "Please provide a password", minlength: "Your password must be at least 5 characters long", equalTo: "Please enter the same password as above" }, email: "Please enter a valid email address", agree: "Please accept our policy" }, errorElement: "em", errorPlacement: function ( error, element ) { // Add the `invalid-feedback` class to the error element error.addClass( "invalid-feedback" ); if ( element.prop( "type" ) === "checkbox" ) { error.insertAfter( element.next( "label" ) ); } else { error.insertAfter( element ); } }, highlight: function ( element, errorClass, validClass ) { $( element ).addClass( "is-invalid" ).removeClass( "is-valid" ); }, unhighlight: function (element, errorClass, validClass) { $( element ).addClass( "is-valid" ).removeClass( "is-invalid" ); } } ); } ); </script> </body> </html>
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2018 群英 版权所有 茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号-36 粤公网安备 44090202000006号 粤工商备P091701000595