Java电商秒杀实战(二)之实现用户登录

Java秒杀实战——实现用户登录
使用两次MD5加密
1) 用户端: PASS = MD5( 明文 + 固定 Salt)

private static final String salt = "1a2b3c4d";

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);
}

2)服务端: PASS = MD5( 用户输入 + 随机 Salt)

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);
}

两次加密的作用:通过两次MD5,可以增大http明文传输过程或数据库被盗后,黑客通过彩虹表等手段反推出明文密码的难度。
首先在pom文件添加依赖:

<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加密工具类MD5Util.java

public class MD5Util {
   
   public static String md5(String src) {
      return DigestUtils.md5Hex(src);
   }
   
   private static final String salt = "1a2b3c4d";
   
   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);
   }
   
   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;
   }
   
   public static void main(String[] args) {
      System.out.println(inputPassToFormPass("123456"));
   }
   
}

数据库表设计
新建数据库表miaosha_user表:
在这里插入图片描述
编写login.html:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>登录</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    
    <!-- jquery -->
    <script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
    <!-- bootstrap -->
    <link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}" />
    <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/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>
    <!-- common.js -->
    <script type="text/javascript" th:src="@{/js/common.js}"></script>
    
</head>
<body>

<form name="loginForm" id="loginForm" method="post"  style="width:50%; margin:0 auto">

   <h2 style="text-align:center; margin-bottom: 20px">用户登录</h2>
   
   <div class="form-group">
           <div class="row">
              <label class="form-label col-md-4">请输入手机号码</label>
           <div class="col-md-5">
              <input id="mobile" name = "mobile" class="form-control" type="text" placeholder="手机号码" required="true"  minlength="11" maxlength="11" />
          </div>
          <div class="col-md-1">
          </div>
       </div>
    </div>
    
    <div class="form-group">
          <div class="row">
              <label class="form-label col-md-4">请输入密码</label>
              <div class="col-md-5">
                 <input id="password" name="password" class="form-control" type="password"  placeholder="密码" required="true" minlength="6" maxlength="16" />
                 </div>
          </div>
   </div>
   
   <div class="row">
             <div class="col-md-5">
                    <button class="btn btn-primary btn-block" type="reset" οnclick="reset()">重置</button>
                 </div>
                 <div class="col-md-5">
                    <button class="btn btn-primary btn-block" type="submit" οnclick="login()">登录</button>
                 </div>
    </div>
    
</form>
</body>
<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();
          if(data.code == 0){
             layer.msg("成功");
             window.location.href="/goods/to_list";
          }else{
             layer.msg(data.msg);
          }
       },
       error:function(){
          layer.closeAll();
       }
   });
}
</script>
</html>

进行JSR303参数校验 + 全局异常处理器
JSR303参数校验
service中的方法入参有许多参数的判断代码,这里为了简化,利用了JSR303参数校验。
首先在pom.xml文件中添加依赖:
在这里插入图片描述
进行自定义参数校验注解:IsMobile、IsMobileValidator

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {IsMobileValidator.class })
public @interface  IsMobile {
   
   boolean required() default true;
   
   String message() default "手机号码格式错误";

   Class<?>[] groups() default { };

   Class<? extends Payload>[] payload() default { };
}
public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {

   private boolean required = false;
   
   public void initialize(IsMobile constraintAnnotation) {
      required = constraintAnnotation.required();
   }

   public boolean isValid(String value, ConstraintValidatorContext context) {
      if(required) {
         return ValidatorUtil.isMobile(value);
      }else {
         if(StringUtils.isEmpty(value)) {
            return true;
         }else {
            return ValidatorUtil.isMobile(value);
         }
      }
   }

}

参数校验完了之后使用该自定义注解:

public class LoginVo {
   
   @NotNull
   @IsMobile
   private String mobile;
   
   @NotNull
   @Length(min=32)
   private String password;
   
   public String getMobile() {
      return mobile;
   }
   public void setMobile(String mobile) {
      this.mobile = mobile;
   }
   public String getPassword() {
      return password;
   }
   public void setPassword(String password) {
      this.password = password;
   }
   @Override
   public String toString() {
      return "LoginVo [mobile=" + mobile + ", password=" + password + "]";
   }
}

在方法中加入@Valid注解
用于验证注解是否符合要求,直接加在变量loginvo之前,在变量中添加验证信息的要求,当不符合要求时就会在方法中返回message 的错误提示信息。

@RequestMapping("/do_login") @ResponseBody public Result<CodeMsg> doLogin(@Valid LoginVo loginVo) {  log.info(loginVo.toString());  seckillUserService.login(loginVo);  return Result.success(CodeMsg.SUCCESS); }'

全局异常处理器
在这里定义全局异常及异常处理器

@ControllerAdvice@ResponseBodypublic class GlobalExceptionHandler { 
 @ExceptionHandler(value = Exception.class) 
 public Result<String> handleException(HttpServletRequest request, Exception ex){ 
  ex.printStackTrace();
      if(ex instanceof GlobalException){ 
        GlobalException gex = (GlobalException)ex;  
         return Result.error(gex.getCm()); 
          } 
          else if(ex instanceof BindException){ 
            BindException bex = (BindException)ex; 
              String message = bex.getAllErrors().get(0).getDefaultMessage(); 
                return Result.error(CodeMsg.BIND_ERROR.fillMsg(message)); 
                 } 
                 else {
                    return Result.error(CodeMsg.SERVER_ERROR);
                      }
                       }
                       }

全局异常:

public class GlobalException extends RuntimeException{

   private static final long serialVersionUID = 1L;
   
   private CodeMsg cm;
   
   public GlobalException(CodeMsg cm) {
      super(cm.toString());
      this.cm = cm;
   }

   public CodeMsg getCm() {
      return cm;
   }

}

分布式session
首先添加uuid工具类

public class UUIDUtil {
   public static String uuid() {
      return UUID.randomUUID().toString().replace("-", "");
   }
}

然后在MiaoshaUserService添加通过token获取user对象方法:

public MiaoshaUser getById(long id) {
  return miaoshaUserDao.getById(id);
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值