springboot+redis+mysql实现静态资源防盗链

程序你得看得懂 2024-09-25 08:22:30
实现静态资源防盗链是为了防止外部网站非法盗用你的网站资源,通常可以通过给资源请求添加签名或者校验Referer头部等方式来实现。在这个示例中,我们将使用Spring Boot、Redis和MySQL来实现一个简单的静态资源防盗链方案。 以下是大致步骤: 配置Spring Boot项目:引入必要的依赖(Spring Boot, Spring Data Redis, Spring Data JPA, MySQL驱动等)。配置数据源和Redis连接。生成防盗链签名:根据请求路径、过期时间和其他参数生成签名。将签名存储在Redis中以便快速验证。校验防盗链签名:在处理静态资源请求时,验证签名是否合法。实现防盗链过滤器:通过过滤器对所有静态资源请求进行拦截和校验。配置Spring Boot项目首先,引入必要的依赖。在pom.xml中添加以下内容: org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-data-redis mysql mysql-connector-java org.apache.commons commons-lang3 配置数据源和Redis连接在application.properties文件中添加MySQL和Redis的配置: # MySQL Configuration spring.datasource.url=jdbc:mysql://localhost:3306/your_database spring.datasource.username=root spring.datasource.password=your_password spring.jpa.hibernate.ddl-auto=update # Redis Configuration spring.redis.host=localhost spring.redis.port=6379生成防盗链签名创建一个工具类用于生成签名: import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.concurrent.TimeUnit; @Component public AntiLeechUtils { @Autowired private StringRedisTemplate redisTemplate; private static final String SECRET_KEY = "your_secret_key"; public String generateSignature(String resourcePath, long expireTime) { String token = resourcePath + "|" + expireTime + "|" + SECRET_KEY; try { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] hash = md.digest(token.getBytes()); StringBuilder hexString = new StringBuilder(); for (byte b : hash) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } public void saveSignature(String resourcePath, String signature, long expireTime) { redisTemplate.opsForValue().set(getRedisKey(resourcePath), signature, expireTime, TimeUnit.SECONDS); } public boolean validateSignature(String resourcePath, String signature) { String redisKey = getRedisKey(resourcePath); String storedSignature = redisTemplate.opsForValue().get(redisKey); return StringUtils.equals(storedSignature, signature); } private String getRedisKey(String resourcePath) { return "anti_leech:" + resourcePath; } }实现防盗链过滤器创建一个过滤器来拦截和校验请求: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public AntiLeechFilter implements Filter { @Autowired private AntiLeechUtils antiLeechUtils; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String uri = httpRequest.getRequestURI(); String signature = httpRequest.getParameter("signature"); // Check if the resource is a static resource and has a signature if (isStaticResource(uri) && signature == null || !antiLeechUtils.validateSignature(uri, signature)) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpResponse.getWriter().write("Access Denied"); return; } chain.doFilter(request, response); } @Override public void destroy() { } private boolean isStaticResource(String uri) { return uri.startsWith("/static/"); } }注册过滤器在Spring Boot应用中注册过滤器: import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @SpringBootApplication public AntiLeechApplication { public static void main(String[] args) { SpringApplication.run(AntiLeechApplication.class, args); } @Bean public FilterRegistrationBean antiLeechFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new AntiLeechFilter()); registrationBean.addUrlPatterns("/static/*"); return registrationBean; } }使用示例生成签名并访问资源: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public ResourceController { @Autowired private AntiLeechUtils antiLeechUtils; @GetMapping("/generateSignature") public String generateSignature(@RequestParam String resourcePath) { long expireTime = 3600; // 1 hour String signature = antiLeechUtils.generateSignature(resourcePath, expireTime); antiLeechUtils.saveSignature(resourcePath, signature, expireTime); return signature; } }访问静态资源时,带上签名参数: http://localhost:8080/static/yourfile.jpg?signature=generated_signature
0 阅读:14

程序你得看得懂

简介:感谢大家的关注