[英]Using JS server time instead of client time to avoid this behavior where users can manipulate results by changing their local machine clock
預期行為
在每次刷新時向用戶顯示來自arr
數組的隨機值(顏色)。 每天應將不同的文件( file-1.json
、 file-2.json
等)加載到arr
中。 這應該在 00:00 UTC 服務器時間重置。 僅應顯示當天相關文件中的值。
意外行為
一切正常,直到用戶更改本地機器/手機上的時鍾。 然后他們也可以有效地看到未來和過去的價值。 日期/時間可以在客戶端進行操作,這是不應該發生的。 每個人都應該得到服務器的時間,不管那是什么。
例子
好:如果您在 2020 年 4 月 18 日訪問/刷新該站點,您應該會從file-1.json
中選擇隨機顏色。
好:如果您在 2020-04-19 訪問/刷新該網站,您應該會從file-2.json
中選擇隨機顏色。
不好:另一方面,如果您在 2020-04-18 將本地時鍾更改為 2020-04-19,則您應該無法從 2020-04-19 獲得隨機顏色,因為該日期在未來. 您仍然應該從今天的文件中獲得一個值,因為它仍然是 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)]);
})
如何復制問題
只需將本地機器或手機的時鍾更改為 2020-04-19。 然后你會得到明天的 colors。
編輯:為了 100% 清楚,無論用戶如何使用他的本地設備設置(更改時鍾、IP 地址等)——他都不應該影響網站時間。
EDIT2:創建此端點以檢索日期和時間: https://bluexpress.netlify.app/.netlify/functions/server/getdate但我不確定它是否是正確的解決方案或如何將其正確集成到站點中。 協助表示贊賞!
那么答案很簡單:不要在客戶端計算文件名,而是將其設為單個 URI,根據日期動態計算服務器上的 JSON。
只要客戶端可以通過更改URI請求任何JSON數據,稍微精明的用戶即使不更改時鍾也可以訪問過去和未來的日子。 作為一般規則,不要信任客戶端,始終確保檢查服務器上的內容。
話雖如此,您也可以保留客戶端邏輯,但讓服務器根據日期拒絕(例如 404 左右)訪問“錯誤日期”的文件。 但是你必須有服務器邏輯來排除客戶端濫用。
答案可以根據
您可以執行其中任何一項並將服務器的時間作為變量獲取 javascript 的可見 scope
然后使用該變量將文件名確定為file-1
file-2
等
要使用 Node.JS 服務器端代碼,請遵循Netlify:Punch Setup
您可以使用世界時間 API的/api/ip
功能根據用戶的公共 ip 地址獲取 api。 就像是
// Modify the getIndex function to receive today's date instead
function getIndex(today){
const startDate = new Date(Date.parse('4/15/2020'));
const offset = getDiffInDays(startDate, today) + 1;
return offset;
}
// Get date from server
function getServerDate(){
// Unfortunately, we need to bypass Cross-Origin Request (CORs)
return fetch(`https://cors-anywhere.herokuapp.com/http://worldtimeapi.org/api/ip`)
// Convert response to json
.then(res=>res.json())
// Get the datetime from object and create a Date object
.then(({datetime})=>new Date(Date.parse(datetime)))
// Get json index based on the date
.then(getIndex);
}
使用上面的 function 你可以簡單
// Get today's date from server
getServerDate()
.then(index=>new Promise(resolve=>{
// Get the json file based on the index returned
$.getJSON(`data-${index}.json`, resolve);
}))
.then(json=>{
// Append to arr and whatever you like here
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.