使用 Springboot + Nginx 的 http_secure_link_module 实现图片防盗链在 Vue 展示

开发 前端
本次方案通过引入 Nginx 的 http_secure_link_module 模块实现了图片防盗链功能,增强了图片资源的安全性。在配置方面,我们使用 Yaml 文件来管理关键配置信息,包括图片域名和 Nginx 的安全链接密钥。

使用 Springboot + Nginx 的 http_secure_link_module 实现图片防盗链并在 Vue 中展示功能

在当今互联网环境中,图片资源的安全性和有效管理至关重要。为了防止未经授权的访问和滥用图片资源,我们采用 Nginx 的 http_secure_link_module 模块来实现图片防盗链功能。这不仅能保护图片的合法使用,还能有效控制资源的访问权限,提升系统的安全性和稳定性。

在本次配置中,我们对 secure_link 模块进行了定制化的设置,以满足特定的业务需求。通过引入 $remote_addr 变量,我们能够更精确地控制访问来源,进一步增强了防盗链的效果。同时,对密钥的配置和 token 、过期时间的生成算法进行优化,确保了只有在合法条件下才能访问图片资源。

Nginx 配置(nginx.conf)

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    # 启用 secure_link 模块
    server {
        listen 80;
        server_name  your_domain;

        # 私有密钥配置
        secure_link_secret your_private_secret;  # 此处的密钥是用于生成和验证 token 的关键元素,需要妥善保管和保密。它参与了 MD5 哈希计算,确保 token 的唯一性和安全性。

        location /images {
            secure_link $arg_token,$arg_expires,$remote_addr;
            secure_link_md5 "$secure_link_secret$uri$arg_expires$remote_addr";  # 这个表达式详细说明了如何根据密钥、图片的 URI、过期时间和客户端的 IP 地址生成 MD5 哈希值,用于验证请求的合法性。

            if ($secure_link = "") {  # 如果 token 为空,直接拒绝访问,返回 403 禁止访问状态码。
                return 403;
            }

            if ($secure_link = "0") {  # 如果 token 验证失败,返回 410 资源已不存在的状态码。
                return 410;
            }

            root /path/to/images;  # 指定图片的实际存储路径,确保 Nginx 能够正确找到并提供服务。
        }
    }
}

Pom.xml 依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>image-security</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Yaml 配置文件(application.yml)

image:
  domain: http://your_domain
nginx:
  secure-link-secret: your_secure_link_secret

ImageController 类(ImageController.java)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.Map;

@Controller
public class ImageController {

    @Autowired
    private Environment environment;

    public String generateImageUrl(String imageName) {
        String imageDomain = environment.getProperty("image.domain");
        // 生成过期时间(假设 1 小时后过期)
        LocalDateTime expirationTime = LocalDateTime.now().plusHours(1);
        long expiresInSeconds = expirationTime.toEpochSecond(ZoneOffset.UTC);

        // 生成 token
        String token = generateToken(imageName, expiresInSeconds);

        return imageDomain + "/images/" + imageName + "?token=" + token + "&expires=" + expiresInSeconds;
    }

    private String generateToken(String uri, long expires) {
        String secret = environment.getProperty("nginx.secure-link-secret");
        String data = uri + expires + secret;
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] hash = digest.digest(data.getBytes());
            return Base64.getUrlEncoder().encodeToString(hash);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Spring Boot 控制器生成图片列表

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/image")
public class ImageController {

    @GetMapping("/list")
    public List<String> getImageList() {
        List<String> imageUrls = new ArrayList<>();
        imageUrls.add(generateImageUrl("image1.jpg"));
        imageUrls.add(generateImageUrl("image2.jpg"));
        // 此处根据实际逻辑生成带有 token 和 expires 参数的图片链接
        return imageUrls;
    }
}

Vue 中展示图片列表

<template>
  <div>
    <ul>
      <li v-for="imageUrl in imageList" :key="imageUrl">
        <img :src="imageUrl" />
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageList: []
    };
  },
  mounted() {
    // 发送请求获取图片列表
    this.$http.get('/image/list')
     .then(response => {
        const imageDomain = '${process.env.VUE_APP_IMAGE_DOMAIN}';
        this.imageList = response.data.map(url => imageDomain + url);
      })
     .catch(error => {
        console.error('获取图片列表失败', error);
      });
  }
};
</script>

总结

本次方案通过引入 Nginx 的 http_secure_link_module 模块实现了图片防盗链功能,增强了图片资源的安全性。在配置方面,我们使用 Yaml 文件来管理关键配置信息,包括图片域名和 Nginx 的安全链接密钥。通过在 ImageController 类中读取这些配置,生成带有令牌和过期时间的图片 URL。在 Vue 端,我们根据配置的域名来完整地构建图片的访问地址。整个方案具有良好的灵活性和可扩展性,能够根据实际业务需求进行调整和优化,有效保护图片资源的合法访问和使用。

责任编辑:武晓燕 来源: 路条编程
相关推荐

2019-08-25 07:15:47

Nginx防盗链Linux

2017-03-22 14:41:43

2011-05-31 14:57:17

PHP盗链

2020-06-15 09:41:47

网络安全数据技术

2024-01-31 23:27:50

盗链Node.js

2020-09-01 16:56:58

华为云

2023-03-30 07:48:46

接口鉴权SpringBoot

2010-03-10 11:11:16

Python编程

2024-02-19 16:25:29

前端Vue.jsJavaScript

2017-07-14 10:10:08

Vue.jsMixin

2009-09-28 13:23:54

HTTP编程

2018-01-18 14:50:56

Nginx实现CDSW

2020-01-14 09:40:00

Nginx负载均衡正向代理

2009-05-14 18:33:33

intelNehalem服务器

2022-11-01 11:55:27

ReactVue3

2010-03-30 18:04:45

Nginx http服

2021-03-30 17:03:02

React开发部署Nginx

2009-12-18 08:40:21

TP-link家庭无线

2010-10-28 10:10:48

oracle存图片

2022-09-20 12:21:25

Vue2Vue3$attrs
点赞
收藏

51CTO技术栈公众号