0
点赞
收藏
分享

微信扫一扫

account-servic(4)

jjt二向箔 2022-04-23 阅读 23
java

1、pom.xml

   <parent>
        <artifactId>common-service</artifactId>
        <groupId>com.ggyy</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
<dependencies>
        <!-- Common Service -->
        <dependency>
            <groupId>com.ggyy</groupId>
            <artifactId>common-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- Repository Service -->
        <dependency>
            <groupId>com.southwind</groupId>
            <artifactId>repository-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- Redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- Jwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <!-- 解决Jwt的JDK版本问题 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

    </dependencies>

2、application.yml

server:
  port: 8084

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/uushop
    username: root
    password: 123456

  application:
    name: account-service

  redis:
    database: 0
    host: 192.168.248.138
    port: 6379
    
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: com/southwind/mapper/xml/*.xml

3、entity 实体类

Admin

@Data
  @EqualsAndHashCode(callSuper = false)
    public class Admin implements Serializable {

    private static final long serialVersionUID=1L;

      @TableId(value = "admin_id", type = IdType.AUTO)
      private Integer adminId;

      /**
     * 账号
     */
      private String username;

      /**
     * 密码
     */
      private String password;

      /**
     * 用户头像
     */
      private String imgUrl;

      /**
     * 用户名称
     */
      private String name;


}

User

@Data
  @EqualsAndHashCode(callSuper = false)
    public class User implements Serializable {

    private static final long serialVersionUID=1L;

      @TableId(value = "user_id", type = IdType.AUTO)
      private Integer userId;

    private String mobile;

    private String password;

      /**
     * 创建时间
     */
        @TableField(fill = FieldFill.INSERT)
      private LocalDateTime createTime;

      /**
     * 修改时间
     */
        @TableField(fill = FieldFill.INSERT_UPDATE)
      private LocalDateTime updateTime;


}

4、用户注册

From–>UserRegisterForm 数据校验

@Data
public class UserRegisterForm {
    @NotEmpty(message = "电话不能为空")
    private String mobile;
    @NotEmpty(message = "校验码不能为空")
    private String code;
    @NotEmpty(message = "密码不能为空")
    private String password;
}

util—》MD5Util 加盐加密

public class MD5Util {
    /**
     * byte[]字节数组 转换成 十六进制字符串
     *
     * @param arr 要转换的byte[]字节数组
     *
     * @return  String 返回十六进制字符串
     */
    private static String hex(byte[] arr) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; ++i) {
            sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    }

    /**
     * MD5加密,并把结果由字节数组转换成十六进制字符串
     *
     * @param str 要加密的内容
     *
     * @return String 返回加密后的十六进制字符串
     */
    private static String md5Hex(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(str.getBytes());
            return hex(digest);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.toString());
            return "";
        }
    }

    /**
     * 生成含有随机盐的密码
     *
     * @param password 要加密的密码
     *
     * @return String 含有随机盐的密码
     */
    public static String getSaltMD5(String password) {
        // 生成一个16位的随机数
        Random random = new Random();
        StringBuilder sBuilder = new StringBuilder(16);
        sBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999));
        int len = sBuilder.length();
        if (len < 16) {
            for (int i = 0; i < 16 - len; i++) {
                sBuilder.append("0");
            }
        }
        // 生成最终的加密盐
        String salt = sBuilder.toString();
        password = md5Hex(password + salt);
        char[] cs = new char[48];
        for (int i = 0; i < 48; i += 3) {
            cs[i] = password.charAt(i / 3 * 2);
            char c = salt.charAt(i / 3);
            cs[i + 1] = c;
            cs[i + 2] = password.charAt(i / 3 * 2 + 1);
        }
        return String.valueOf(cs);
    }

    /**
     * 验证加盐后是否和原密码一致
     *
     * @param password 原密码
     *
     * @param password 加密之后的密码
     *
     *@return boolean true表示和原密码一致   false表示和原密码不一致
     */
    public static boolean getSaltverifyMD5(String password, String md5str) {
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i += 3) {
            cs1[i / 3 * 2] = md5str.charAt(i);
            cs1[i / 3 * 2 + 1] = md5str.charAt(i + 2);
            cs2[i / 3] = md5str.charAt(i + 1);
        }
        String Salt = new String(cs2);
        return md5Hex(password + Salt).equals(String.valueOf(cs1));
    }

    public static void main(String[] args) {
        // 原密码
        String plaintext = "123456";
        String s1 = MD5Util.getSaltMD5(plaintext);
        System.out.println(s1);

//        String s = MD5Util.getSaltMD5(plaintext);
//        System.out.println(s);

        // 获取加盐后的MD5值
//        String ciphertext = MD5Util.getSaltMD5(plaintext);
//        System.out.println("加盐后MD5:" + ciphertext);
//        System.out.println("是否是同一字符串:" + MD5Util.getSaltverifyMD5(plaintext, ciphertext));
//        System.out.println(MD5Util.getSaltverifyMD5(plaintext, "c1df1b61022d11d41829f63a08ff5824427f40af83919878"));
    }

}

controller
校验手机号的时候用了 common–server下的
RegexValidateUtil.checkMobile

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/register")
    public ResultVO register(@Valid @RequestBody UserRegisterForm userRegisterForm, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            throw new ShopException(ResponseEnum.USER_INFO_NULL.getMsg());
        }
        //判断手机号是否正确
        Assert.isTrue(RegexValidateUtil.checkMobile(userRegisterForm.getMobile()), ResponseEnum.MOBILE_ERROR);
        //判断手机号是否已经注册
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", userRegisterForm.getMobile());
        User one = this.userService.getOne(queryWrapper);
        if(one!=null){
            throw new ShopException(ResponseEnum.USER_MOBILE_EXIST.getMsg());
        }
        String code = (String) this.redisTemplate.opsForValue().get("uushop-sms-code-" + userRegisterForm.getMobile());
        //状态码比较--枚举
        Assert.equals(code, userRegisterForm.getCode(), ResponseEnum.USER_CODE_ERROR);
        //注册
        User user = new User();
        user.setMobile(userRegisterForm.getMobile());
        user.setPassword(MD5Util.getSaltMD5(userRegisterForm.getPassword()));
        //存数据
        boolean save = this.userService.save(user);
        if(save) return ResultVOUtil.success(null);
        return ResultVOUtil.fail(null);
    }
}

5、用户登录

form–》UserLoginForm 非空校验

@Data
public class UserLoginForm {
    @NotEmpty(message = "电话不能为空")
    private String mobile;
    @NotEmpty(message = "密码不能为空")
    private String password;
}

vo–>UserVO

@Data
public class UserVO {
    private Integer userId;
        private String mobile;
        private String password;
        private String token;
}

util–>JWT生成token
jwt --基于web的验证机制(令牌)

public class JwtUtil { 
     //有限时间(毫秒)
        private static long tokenExpiration = 1000 * 60 * 60 * 24;
    private static String tokenSignKey = "a1d23mi789n";
     
     //加密
    public static String createToken(Integer id,String mobile){
        String token = Jwts.builder()
                //载荷:自定义信息
                .claim("id", id)
                .claim("mobile", mobile)
                //载荷:默认信息
                .setSubject("uushop-user") //令牌主题
                //现在事件+有限时间
                .setExpiration(new Date(System.currentTimeMillis()+tokenExpiration)) //过期时间
                .setId(UUID.randomUUID().toString())
                //签名哈希
                .signWith(SignatureAlgorithm.HS256, tokenSignKey)
                //组装jwt字符串----
                .compact();
        return token;
    }
    
    //解密(判断有没有异常)
    public static boolean checkToken(String token){
        if(StringUtils.isEmpty(token)){ //非空
            return false;
        }
        try {
        //通过密钥解密
        //正常,没报错---token是对的
        //解密,报错--错
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        } catch (Exception e) {
            return false;
        }
        return true;
    }



    //测试
 public static void main(String[] args) {
         //①生成token
//        String token = JwtUtil.createToken(26, "13998786612");
//        System.out.println(token);
        //②复制--校验
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MjYsIm1vYmlsZSI6IjEzOTk4Nzg2NjEyIiwic3ViIjoidXVzaG9wLXVzZXIiLCJleHAiOjE2MzM3ODQ4MDksImp0aSI6IjIwNTY2ZjlhLTU3MDMtNDc5My1hNjRmLTRkOGJmMjcyMjRjYSJ9.J-4qI1CACtF0g_zEZ22D7IiahIGX4Z3qgpxn0vtdTUM";
        //③checkToken验证
        boolean b = JwtUtil.checkToken(token);
        System.out.println(b);
}
在这里插入代码片

controller


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
  
   @GetMapping("/login")
    public ResultVO login(@Valid UserLoginForm userLoginForm,BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            throw new ShopException(ResponseEnum.USER_INFO_NULL.getMsg());
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", userLoginForm.getMobile());
        User one = this.userService.getOne(queryWrapper);
        if(one == null){
            throw new ShopException(ResponseEnum.USER_MOBILE_NULL.getMsg());
        }
        boolean saltverifyMD5 = MD5Util.getSaltverifyMD5(userLoginForm.getPassword(), one.getPassword());
        if(!saltverifyMD5){
            throw new ShopException(ResponseEnum.PASSWORD_ERROR.getMsg());
        }
        UserVO userVO = new UserVO();
        userVO.setMobile(one.getMobile());
        userVO.setUserId(one.getUserId());
        userVO.setPassword(one.getPassword());
        userVO.setToken(JwtUtil.createToken(one.getUserId(), one.getMobile()));
        return ResultVOUtil.success(userVO);
    }
    }

token验证

controller

    @GetMapping("/checkToken")
    public ResultVO checkToken(HttpServletRequest request){
        String token = request.getHeader("token");
        boolean b = JwtUtil.checkToken(token);
        if(b) return ResultVOUtil.success(null);
        return ResultVOUtil.fail(null);
    }
举报

相关推荐

0 条评论