SpringBoot中驗(yàn)證用戶上傳的圖片資源的方法
允許用戶上傳圖片資源(頭像,發(fā)帖)是APP常見的需求,特別需要把用戶的資源IO到磁盤情況下,需要防止壞人提交一些非法的文件,例如木馬,webshell,可執(zhí)行程序等等。這類非法文件不僅會(huì)導(dǎo)致客戶端圖片資源顯示失敗,而且還會(huì)給服務(wù)器帶來安全問題。
通過文件后綴判斷文件的合法性
這種方式比較常見,也很簡(jiǎn)單,是目前大多數(shù)APP選擇的做法。
public Object upload (@RequestParam("file") MultipartFile multipartFile) throws IllegalStateException, IOException { // 原始文件名稱 String fileName = multipartFile.getOriginalFilename(); // 解析到文件后綴,判斷是否合法 int index = fileName.lastIndexOf("."); String suffix = null; if (index == -1 || (suffix = fileName.substring(index + 1)).isEmpty()) { return "文件后綴不能為空"; } // 允許上傳的文件后綴列表 Set<String> allowSuffix = new HashSet<>(Arrays.asList("jpg", "jpeg", "png", "gif")); if (!allowSuffix.contains(suffix.toLowerCase())) { return "非法的文件,不允許的文件類型:" + suffix; } // 序列化到磁盤中的文件上傳目錄, /upload // FileCopyUtils.copy 方法會(huì)自動(dòng)關(guān)閉流資源 FileCopyUtils.copy(multipartFile.getInputStream(), Files.newOutputStream(Paths.get("D://upload", fileName), StandardOpenOption.CREATE_NEW)); // 返回相對(duì)訪問路徑,文件名極有可能帶中文或者空格等字符,進(jìn)行uri編碼 return "/" + UriUtils.encode(fileName, StandardCharsets.UTF_8); }
使用 ImageIO 判斷是否是圖片
這個(gè)方法就比較嚴(yán)格了,在判斷后綴的基礎(chǔ)上,使用Java的ImageIO
類去加載圖片,嘗試讀取其寬高信息,如果不是合法的圖片資源。則無法讀取到這兩個(gè)數(shù)據(jù)。就算是把非法文件修改了后綴,也可以檢測(cè)出來。
public Object upload (@RequestParam("file") MultipartFile multipartFile) throws IllegalStateException, IOException { // 原始文件名稱 String fileName = multipartFile.getOriginalFilename(); // 解析到文件后綴 int index = fileName.lastIndexOf("."); String suffix = null; if (index == -1 || (suffix = fileName.substring(index + 1)).isEmpty()) { return "文件后綴不能為空"; } // 允許上傳的文件后綴列表 Set<String> allowSuffix = new HashSet<>(Arrays.asList("jpg", "jpeg", "png", "gif")); if (!allowSuffix.contains(suffix.toLowerCase())) { return "非法的文件,不允許的文件類型:" + suffix; } // 臨時(shí)文件 File tempFile = new File(System.getProperty("java.io.tmpdir"), fileName); try { // 先把文件序列化到臨時(shí)目錄 multipartFile.transferTo(tempFile); try { // 嘗試IO文件,判斷文件的合法性 BufferedImage bufferedImage = ImageIO.read(tempFile); bufferedImage.getWidth(); bufferedImage.getHeight(); } catch (Exception e) { // IO異常,不是合法的圖片文件,返回異常信息 return "文件不是圖片文件"; } // 復(fù)制到到上傳目錄 FileCopyUtils.copy(new FileInputStream(tempFile), Files.newOutputStream(Paths.get("D://upload", fileName), StandardOpenOption.CREATE_NEW)); // 返回相對(duì)訪問路徑 return "/" + UriUtils.encode(fileName, StandardCharsets.UTF_8); } finally { // 響應(yīng)客戶端后,始終刪除臨時(shí)文件 tempFile.delete(); } }
總結(jié)
使用ImageIo
的方式更為保險(xiǎn),但是需要多幾次IO操作。比較消耗性能。而且今天APP大都是用云存儲(chǔ)服務(wù),類似于阿里云的OSS。直接就把客戶端上傳的文件PUT到了云端,才不管用戶上傳的圖片是不是真正的圖片,非法上傳,最多導(dǎo)致客戶端不能顯示而已,但是威脅不了服務(wù)器的安全。
原文:https://springboot.io/t/topic/2231
到此這篇關(guān)于在SpringBoot中驗(yàn)證用戶上傳的圖片資源的文章就介紹到這了,更多相關(guān)SpringBoot驗(yàn)證用戶上傳的圖片資源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Gradle構(gòu)建多模塊項(xiàng)目的方法步驟
這篇文章主要介紹了Gradle構(gòu)建多模塊項(xiàng)目的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05SpringBoot使用@NotEmpty、@NotBlank、@NotNull注解進(jìn)行參數(shù)校驗(yàn)
我們經(jīng)常需要對(duì)請(qǐng)求參數(shù)進(jìn)行校驗(yàn),本文主要介紹了SpringBoot使用@NotEmpty、@NotBlank、@NotNull注解進(jìn)行參數(shù)校驗(yàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-0810個(gè)經(jīng)典的Java main方法面試題
這篇文章主要為大家分享了10個(gè)經(jīng)典的Java main方法面試題,與其說是Java面試題,其實(shí)也是Java的一些最基礎(chǔ)知識(shí)問題,感興趣的小伙伴們可以參考一下2016-01-01基于Session的國(guó)際化實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄赟ession的國(guó)際化實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08