欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot 校驗(yàn)用戶上傳的圖片文件(兩種方式)

 更新時(shí)間:2023年11月09日 12:02:13   作者:Doker 多克  
圖片上傳是現(xiàn)代應(yīng)用中非常常見的一種功能,也是風(fēng)險(xiǎn)比較高的一個(gè)地方,惡意用戶可能會上傳一些病毒、木馬,本文給大家介紹兩種對圖片文件進(jìn)行校驗(yàn)的方法,感興趣的朋友一起看看吧

圖片上傳是現(xiàn)代應(yīng)用中非常常見的一種功能,也是風(fēng)險(xiǎn)比較高的一個(gè)地方。惡意用戶可能會上傳一些病毒、木馬。這些東西不僅嚴(yán)重威脅服務(wù)器的安全還浪費(fèi)了帶寬,磁盤等資源。所以,在圖片上傳的接口中,一定要對用戶上傳的文件進(jìn)行嚴(yán)格的校驗(yàn)。

本文介紹了 2 種對圖片文件進(jìn)行驗(yàn)證的方法可供你參考。

一、文件后綴校驗(yàn)

通過文件后綴(也就是文件擴(kuò)展名,通常用于表示文件的類型),進(jìn)行文件類型校驗(yàn)這是最常見的做法。

圖片文件的后綴類型有很多,常見的只有:jpg、jpeg、gifpng、webp。我們可以在配置或者代碼中定義一個(gè)“允許上傳的圖片后綴”集合,用于校驗(yàn)用戶上傳的圖片文件。

package cn.springdoc.demo.web.controller;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/upload")
public class UploadController {
    // 允許上傳的圖片類型的后綴集合
    static final Set<String> imageSuffix = Set.of("jpg", "jpeg", "gif", "png", "webp");
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<String> upload (@RequestParam("file") MultipartFile file ) throws IllegalStateException, IOException{
        // 文件的原始名稱
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return ResponseEntity.badRequest().body("文件名稱不能為空");
        }
        // 解析出文件后綴
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            return ResponseEntity.badRequest().body("文件后綴不能為空");
        }
        String suffix = fileName.substring(index + 1);
        if (!imageSuffix.contains(suffix.trim().toLowerCase())) {
            return ResponseEntity.badRequest().body("非法的文件類型");
        }
        // IO 到程序運(yùn)行目錄下的 public 目錄,這是默認(rèn)的靜態(tài)資源目錄
        Path dir = Paths.get(System.getProperty("user.dir"), "public");
        if (!Files.isDirectory(dir)) {
            // 創(chuàng)建目錄
            Files.createDirectories(dir);
        }
        file.transferTo(dir.resolve(fileName));
        // 返回相對訪問路徑
        return ResponseEntity.ok("/" + fileName);
    }
}

如上,代碼很簡單。先是獲取客戶端文件的名稱,再從名稱獲取到文件的后綴。確定是合法文件后再 IO 到本地磁盤。

二、使用 ImageIO 校驗(yàn)

由于文件的后綴是可編輯的,惡意用戶可以把一個(gè) exe 文件的后綴改為 jpg 再上傳到服務(wù)器。于是這種情況下,上面的這種校驗(yàn)方式就會失效,惡意文件會被 IO 到磁盤。

在基于上面的方法進(jìn)行校驗(yàn)后,我們可以先把文件 IO 到臨時(shí)目錄,再使用 ImageIO 類去加載圖片文件,如果 Images 加載的文件不是圖片,則會返回 null。

package cn.springdoc.demo.web.controller;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/upload")
public class UploadController {
    // 允許上傳的圖片類型的后綴集合
    static final Set<String> imageSuffix = Set.of("jpg", "jpeg", "gif", "png", "webp");
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file)
            throws IllegalStateException, IOException {
        // 文件的原始名稱
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return ResponseEntity.badRequest().body("文件名稱不能為空");
        }
        // 解析出文件后綴
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            return ResponseEntity.badRequest().body("文件后綴不能為空");
        }
        String suffix = fileName.substring(index + 1);
        if (!imageSuffix.contains(suffix.trim().toLowerCase())) {
            return ResponseEntity.badRequest().body("非法的文件類型");
        }
        // 獲取系統(tǒng)中的臨時(shí)目錄
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        // 臨時(shí)文件使用 UUID 隨機(jī)命名
        Path tempFile = tempDir.resolve(Paths.get(UUID.randomUUID().toString()));
        // copy 到臨時(shí)文件
        file.transferTo(tempFile);
        try {
            // 使用 ImageIO 讀取文件
            if (ImageIO.read(tempFile.toFile()) == null) {
                return ResponseEntity.badRequest().body("非法的文件類型");
            }
            // 至此,這的確是一個(gè)圖片資源文件
            // IO 到運(yùn)行目錄下的 public 目錄
            Path dir = Paths.get(System.getProperty("user.dir"), "public");
            if (!Files.isDirectory(dir)) {
                // 創(chuàng)建目錄
                Files.createDirectories(dir);
            }
            Files.copy(tempFile, dir.resolve(fileName));
            // 返回相對訪問路徑
            return ResponseEntity.ok("/" + fileName);
        } finally {
            // 始終刪除臨時(shí)文件
            Files.delete(tempFile);
        }
    }
}

這種方式更為嚴(yán)格,不但要校驗(yàn)文件后綴還要校驗(yàn)文件內(nèi)容。弊端也顯而易見,會耗費(fèi)更多的資源!

1、ImageIO.read 方法

最后說一下 ImageIO.read 方法,它會從系統(tǒng)中已注冊的 ImageReader 中選擇一個(gè) Reader 對圖片進(jìn)行解碼,如果沒有 Reader 能夠解碼文件,則返回 null。也就是說,如果上傳的圖片類型,在系統(tǒng)中沒有對應(yīng)的 ImageReader 也會被當(dāng)做是“非法文件”。

例如:webp 類型的圖片文件,ImageIO.read 就讀取不了,因?yàn)?JDK 沒有預(yù)置讀取 webp 圖片的 ImageReader。

要解決這個(gè)問題,可以添加一個(gè) webp-imageio 依賴。

<!-- https://mvnrepository.com/artifact/org.sejda.imageio/webp-imageio -->
<dependency>
    <groupId>org.sejda.imageio</groupId>
    <artifactId>webp-imageio</artifactId>
    <version>0.1.6</version>
</dependency>

webp-imageio 庫提供了 webp 圖片的 ImageReader 實(shí)現(xiàn),并以 SPI 的形式注冊到了系統(tǒng)中,不要寫其他任何代碼就可以成功讀取。

到此這篇關(guān)于Spring Boot 校驗(yàn)用戶上傳的圖片文件的文章就介紹到這了,更多相關(guān)Spring Boot 校驗(yàn)上傳圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA(SpringBoot)集成Jasypt進(jìn)行加密、解密功能

    JAVA(SpringBoot)集成Jasypt進(jìn)行加密、解密功能

    Jasypt是一個(gè)Java庫,專門用于簡化加密和解密操作,提供多種加密算法支持,集成到SpringBoot等框架中,通過使用Jasypt,可以有效保護(hù)配置文件中的敏感信息,如數(shù)據(jù)庫密碼等,避免被未授權(quán)訪問,Jasypt還支持自定義加密器,提高擴(kuò)展性和安全性,適用于各種需要加密保護(hù)應(yīng)用場景
    2024-09-09
  • Hibernate中Session.get()方法和load()方法的詳細(xì)比較

    Hibernate中Session.get()方法和load()方法的詳細(xì)比較

    今天小編就為大家分享一篇關(guān)于Hibernate中Session.get()方法和load()方法的詳細(xì)比較,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java文件斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理解析

    Java文件斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理解析

    這篇文章主要介紹了Java文件斷點(diǎn)續(xù)傳實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 深入淺析java中flyway使用簡介

    深入淺析java中flyway使用簡介

    Flyway是獨(dú)立于數(shù)據(jù)庫的應(yīng)用、管理并跟蹤數(shù)據(jù)庫變更的數(shù)據(jù)庫版本管理工具。這篇文章主要介紹了flyway使用簡介,需要的朋友可以參考下
    2020-07-07
  • Spring排序機(jī)制之接口與注解的使用方法

    Spring排序機(jī)制之接口與注解的使用方法

    本文介紹了Spring中多種排序機(jī)制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了詳細(xì)示例,并指導(dǎo)如何選擇合適的排序機(jī)制來控制Bean的加載順序和優(yōu)先級,感興趣的朋友一起看看吧
    2025-02-02
  • SpringBoot整合MyCat實(shí)現(xiàn)讀寫分離的方法

    SpringBoot整合MyCat實(shí)現(xiàn)讀寫分離的方法

    這篇文章主要介紹了SpringBoot整合MyCat實(shí)現(xiàn)讀寫分離的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot入門之集成JSP的示例代碼

    SpringBoot入門之集成JSP的示例代碼

    這篇文章主要介紹了SpringBoot入門之集成JSP的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • SpringMVC post請求中文亂碼問題解決

    SpringMVC post請求中文亂碼問題解決

    這篇文章主要介紹了SpringMVC post請求中文亂碼問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • IDEA-Maven項(xiàng)目的jdk版本設(shè)置方法

    IDEA-Maven項(xiàng)目的jdk版本設(shè)置方法

    我們需要設(shè)置jdk的版本,不然會提示導(dǎo)致語法錯(cuò)誤,這篇文章主要介紹了IDEA-Maven項(xiàng)目的jdk版本設(shè)置方法,小編覺得不錯(cuò),一起來了解一下
    2019-04-04
  • 詳解Spring Boot中MyBatis的使用方法

    詳解Spring Boot中MyBatis的使用方法

    mybatis初期使用比較麻煩,需要各種配置文件、實(shí)體類、dao層映射關(guān)聯(lián)、還有一大推其它配置。當(dāng)然mybatis也發(fā)現(xiàn)了這種弊端。下面通過本文給大家詳細(xì)介紹Spring Boot中MyBatis的使用方法,感興趣的朋友一起看看吧
    2017-07-07

最新評論