반응형

서버 특정 경로에 이미지파일이 존재할때 해당 파일의 경로나 파일등의 정보를 노출하지 않고 바이너리 데이터를 통해 이미지를 표현하고 싶었습니다.

특히나 개인정보가 담긴 이미지 등의 데이터는 더욱 민감할 수 있는데 이런 형태의 인증 처리가 없을 경우 최악으로 인가되지 않은 특정 클라이언트가 url/경로/파일명 형태로 마구잡이로 접근하여 개인정보를 가져갈 수 있는 위험이 있다.

 

해당 위치 접근을 바로 할 수 없도록 막았고 가져오기 위해 인증된 계정만 서버에서 데이터를 전달하도록 처리하였다.

 

Controller.java

@Controller
public class AdminController {
	
	private final Logger logger = Logger.getLogger(AdminController.class);
    
	@RequestMapping(value={"preView"}, method=RequestMethod.POST)
	private @ResponseBody Map<String, Object> preView(@RequestParam Map<String, Object> params, final HttpServletRequest request) throws Exception {
		String fileName = (String) params.get("fileName");
		String filePath = request.getSession().getServletContext().getRealPath("/") + "upload/";
		File file = new File(filePath + fileName);
		if(file.exists()) {
			params.put("exist", true);
			params.put("blob", FileUtils.readFileToByteArray(file));
		}else {
			params.put("exist", false);
		}
		return params;
	}
}

요청한 파라미터의 파일 데이터를 기준으로 존재하면 apache.commons 의 FileUtils 를 사용하여 File 데이터를 바이트로 변환했습니다.

 

request.js

function preview(file){
  $.ajax({
    type:"POST",
    url:"preView",
    data:fileName="+file,
    dataType: "json",
    success: function(args){
      if(args.exist){
      	$("#img").attr("src", "data:image/png;base64," + res.blob);
      }else{
      	alert("파일이 존재하지 않습니다.");
      }
    },
    error: function(error){
    	console.log(error);
    	alert("오류가 발생했습니다.");
    }
  });
}

서버 특정 경로에 존재하는 파일명.확장자 형태로 요청하면 서버에서 존재하는지 확인 후 byteArray 형태로 데이터를 전달해주면 base64를 통해 데이터를 이진데이터로 읽어들여서 이미지를 표출해준다. 다만 매번 이미지를 가져올때 마다 서버에서 통신이 발생하고 이진데이터로 노출하다보니 속도가 미세하게 느려지는게 느껴진다.

반응형