预期行为
每次刷新时向用户显示 arr
数组中的随机值(颜色)。每天应将不同的文件(file-1.json
、file-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/