javascript - 使用 JS 服务器时间而不是客户端时间来避免这种行为,即用户可以通过更改本地计算机时钟来操纵结果

标签 javascript jquery json date time

预期行为

每次刷新时向用户显示 arr 数组中的随机值(颜色)。每天应将不同的文件(file-1.jsonfile-2.json 等)加载到 arr 中。这应该在 00:00 UTC 服务器时间重置。仅应显示当天关联文件中的值。

意外行为

一切正常,直到用户更改本地计算机/电话上的时钟。然后他们也可以有效地看到 future 和过去的值(value)。日期/时间可以在客户端进行操作,这是不应该发生的。每个人都应该获得服务器的时间,无论是什么。

示例

  • :如果您在 2020 年 4 月 18 日访问/刷新网站,您应该会获得从 file-1.json 中挑选的随机颜色。

  • :如果您在 2020 年 4 月 19 日访问/刷新网站,您应该会获得从 file-2.json 中挑选的随机颜色。

  • 不好:另一方面,如果您在 2020 年 4 月 18 日将本地时钟更改为 2020 年 4 月 19 日,您不应该能够从 2020-04-19 获得随机颜色,因为该日期是 future 的日期。您仍然应该从今天的文件中获取值,因为它仍然是 2020-04-18 服务器时间。

script.js:

// Store today's date
const today = new Date();
var arr = [];
// Define milliseconds per day
const msPerDay = 1000*60*60*24;

// Uncomment line below to test future date by using the getDateByOffset() function
//const today = getDateByOffset(1);

// Get difference (in days) between two dates
function getDiffInDays(date1, date2){
    // `|0` is same as Math.floor(...)
    return ((date2.getTime() - date1.getTime())/msPerDay)|0;
}
// Get date by offset in days (Useful for testing tomorrow's date and so on)
function getDateByOffset(days=0){
    const today = new Date();
    return new Date((today.getTime()/msPerDay + days)*msPerDay);
}

// Get offset index for the json file
function getIndex(){
    // Define the starting date for "file-1.json"
    const startDate = new Date(Date.parse('4/18/2020'));
    // Will range from 1 instead of 0
    return getDiffInDays(startDate, today) + 1;
}
new Promise(resolve=>{
    // Get the json file based on the offset
    $.getJSON(`file-${getIndex()}.json`, resolve);
})
.then(json=>{
    // Add it to the `arr` array
    arr = [...arr,...json];
})
.then(()=>{
    console.log(arr);
    $("#show").text(arr[Math.floor(Math.random() * arr.length)]);
})

<强> DEMO on Netlify

如何重现问题

只需将本地计算机或手机的时钟更改为 2020-04-19。然后你就会得到明天的颜色。

编辑:为了 100% 清楚,无论用户如何使用本地设备设置(更改时钟、IP 地址等),他都不应该能够影响网站时间。

EDIT2:创建此端点以检索日期和时间:https://bluexpress.netlify.app/.netlify/functions/server/getdate但我不确定这是否是正确的解决方案或如何将其正确集成到网站中。感谢您的帮助!

最佳答案

那么答案很简单:不要在客户端计算文件名,而是将其设为单个 URI,根据日期在服务器上动态计算 JSON。

只要客户端可以通过更改 URI 来请求任何 JSON 数据,稍微懂一点的用户就可以访问过去和 future 的日子,甚至无需更改时钟。作为一般规则,不要信任客户端,始终确保检查服务器上的内容。

话虽这么说,您也可以保留客户端逻辑,但让服务器根据日期拒绝(例如 404 左右)访问“错误日期”的文件。但是您必须有服务器逻辑来排除客户端滥用。

关于javascript - 使用 JS 服务器时间而不是客户端时间来避免这种行为,即用户可以通过更改本地计算机时钟来操纵结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61286220/

相关文章:

javascript - jQuery 双对象构造函数 - 例如$($(这个))

javascript - jscrollpane设置垂直滚动条轨道高度

javascript - 使用 jQuery load() 内容时无法使工具提示正常工作

javascript - D3js - 将数据绑定(bind)到多个圆环图

python - 将 Flask 表单值转换为 int

php - 在js中定义一个php变量

javascript - 从 2005 年的 Javascript 意大利面条代码转移到 2013 年的模块化 Javascript?

javascript - Jquery 如何为每个 ajax 响应更改 url

javascript - 使用 jQuery 更改段落中的符号

java - Android:如何从 JSON 获取某些值