0
点赞
收藏
分享

微信扫一扫

使用Jwt验证登录demo

捌柒陆壹 2022-03-12 阅读 37

一、准备

  1. 依赖
<!--jwt依赖-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.7</version>
</dependency>
  1. 使用Md5工具对数据库密码加密
@Slf4j
public class Md5Utils {

    public static String getMD5String(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
            //一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("{}计算md5异常:{}",stackTraceElement,e.getMessage());
            return null;
        }
    }

}
  1. 生成rsa的私钥和公钥,可以在线生成,不要空格不要换行,不要其他的字符
  2. 从数据库获取用户名和使用md5加密的密码
@Override
    public ResultVo login(ManagerDto managerDto) {
        if (ObjectUtils.isEmpty(managerDto)){
            return new ResultVo().failure(ResultCode.PARAMETER_INVALID);
        }
        try {
            String userName = managerDto.getUserName();
            String password = managerDto.getPassword();
            IdleManagerEntity manager = managerMapper.getManager(userName);
            if (manager == null){
                log.info("用户名为空");
                return new ResultVo().failure(ResultCode.USER_NULL);
            }

            String md5String = Md5Utils.getMD5String(password);
            if (!md5String.equals(manager.getMd5Password())){
                log.info("密码错误");
                return new ResultVo().failure(ResultCode.PASSWORD_ERROR);
            }

            log.info(" {} already login",userName);
            manager.setMd5Password("");
            try {
                // 获取私钥
                PrivateKey privateKey = RsaUtils.getPrivateKey(ResourceUtils.getFile("src/main/resources/rsa.pri").getPath());
                // 生成token
                String token = JwtUtils.generateTokenExpireInMinutes(manager, privateKey, 1);
                return new ResultVo().success(token);
            } catch (Exception e) {
                StackTraceElement stackTraceElement = e.getStackTrace()[0];
                log.error("{}token error:{}",stackTraceElement,e.getMessage());
                return new ResultVo().failure(ResultCode.SYSTEM_ERROR);
            }
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("登录异常");
            return new ResultVo().failure(ResultCode.SYSTEM_ERROR);
        }
    }

二、需要对请求方法进行拦截,判断是否携带token或者是否过期

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        //放行请求方法为OPTIONS的请求
        String method = request.getMethod();
        if(method.equals("OPTIONS")){
            return  true;
        }
        //获取请求头中的请求信息
        String token = request.getHeader("token");
        //使用公钥解密进行校验
        //获取公钥
        PublicKey publicKey = RsaUtils.getPublicKey(
                ResourceUtils.getFile("src/main/resources/rsa.pub").getPath());
        try {
            IdleManagerEntity manager = (IdleManagerEntity) JwtUtils.getInfoFromToken(token, publicKey, IdleManagerEntity.class);
            return true;
        }catch (Exception e){
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("{}token error:{}",stackTraceElement,e.getMessage());
        }
        //失败要响应json数据给前端
        response.sendRedirect(request.getContextPath()+"/login");
        return false;
    }

}

三、需要将拦截器注册到springmvc中,放行登录请求

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    /**
     * 注册拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /**
         * addInterceptor 注册拦截器
         * addPathPatterns 配置拦截规则
         */
        registry.addInterceptor(loginInterceptor)
                .excludePathPatterns("/login")
                .addPathPatterns("/**");
    }
}
举报

相关推荐

0 条评论