阻止用户使用ajax提交自己的图像?

时间:2017-04-30 00:58:00

标签: javascript php html5 canvas server

我一直在用这种方式让人们在画布上绘制内容并将其上传到服务器。 它工作正常,除了人们能够插入自己的图像(我的朋友测试它)

以下是它的作用:

  1. 人点击“提交”他们的画布保存到base64并使用$ .post()发送

  2. $ .post()中的php文件运行并将文件保存到服务器中的文件

  3. 有没有办法阻止用户提交自己的图片,我已经检查过图片尺寸等等,但他们只是调整尺寸并提交。 (我认为由于我的小型服务器,php绘制图像的能力不会起作用)

3 个答案:

答案 0 :(得分:1)

  

是否有任何阻止用户提交自己图片的方法

不。

任何人都可以通过完全绕过客户端代码来上传他们想要的任何内容。除了hacky启发式之外,你无能为力。 (他们已经在页面上了一段时间吗?是否检测到鼠标移动或屏幕触摸?他们真的画了什么东西吗?)这些东西也可以伪造,这只是一个头发更麻烦的黑客。不要为此烦恼,你会为自己创造更多的问题,而不是你要解决的问题。

答案 1 :(得分:1)

根据我的理解,如果你的应用程序是一个简单的绘图工具,那么一种简单的方法就是只发送一个包含所有用户手势的JSON,而不是保存图像本身。

这样,即使一个人仍然可以绕过你的应用程序,并且无法控制(即以编程方式)生成图像,他们也无法在服务器上保存例如图像。

这还允许您在保存之前对数据结构服务器端执行完整性检查,并在您的应用中实现cancel功能。

然而,一个反作用的结果是随后增加的数据以节省大型图纸(但减少了较小的图纸)。

const ctx = canvas.getContext('2d');

let drawing = false,
  rect = canvas.getBoundingClientRect(),
  paths = [];

let savedData = '[]';

save_btn.onclick = _ => {
  savedData = JSON.stringify(paths);
  console.clear();
  console.log(savedData);
  // here send this JSON data to the server
};
load_btn.onclick = _ => {
  // easy to grab from server too
  paths = JSON.parse(savedData);
  draw();
  };
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // at each draw, we loop over all our paths
  paths.forEach(p => {
    ctx.lineWidth = p.strokeWidth;
    ctx.strokeStyle = p.color;
    ctx.beginPath();
    const l = p.list;
    ctx.moveTo(l[0], l[1]);
    for (let i = 2; i < l.length; i += 2) {
      ctx.lineTo(l[i], l[i + 1]);
    }
    ctx.stroke();
  });
}
// returns a new path object
function makePath() {
  return {
    color: randCol(),
    list: [],
    strokeWidth: (Math.random() * 10) + 1
  };
}

canvas.onmouseup = canvas.onmouseleave = e => {
  drawing = false;
};
canvas.onmousedown = e => {
  paths.push(makePath());
  drawing = true;
}
canvas.onmousemove = throttle(e => {
  if (!drawing) return;
  // to minimize the size of our JSON data
  // we fix the coordinates to precision(2)
  let x = ~~((e.clientX - rect.left) *10)/10;
  let y = ~~((e.clientY - rect.top) *10)/10;
  paths[paths.length - 1].list.push(x, y);
  draw();
});

window.onresize = window.onscroll = throttle(e => rect = canvas.getBoundingClientRect());

function throttle(callback) {
  let active = false;
  let evt;
  const handler = function() {
    active = false;
    callback(evt);
  }
  return function handleEvent(e) {
    evt = e;
    if (!active) {
      active = true;
      requestAnimationFrame(handler);
    };
  };
}

function randCol() {
  const letters = '0123456789ABCDEF'.split('');
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.round(Math.random() * 15)];
  }
  return color;
}
canvas{
  border: 1px solid;
  }
<button id="save_btn">save</button>
<button id="load_btn">load last saved</button><br>
<canvas id="canvas"></canvas>

答案 2 :(得分:0)

您可以检查图像数据,例如图像高度,宽度,甚至图像大小和颜色,具体取决于画布中呈现的内容。举个例子,假设画布是250 x 250像素,它只使用蓝色,红色和绿色的颜色渲染2D正方形。如果有三种以上的颜色,如果颜色不仅是蓝色,红色和绿色,或者如果画布不是250 x 250,则拒绝它。您还可以检查用户代理中的“referrer”值,但这可以轻松更改。