Strategy for getting a “real” device time while offline
Clash Royale CLAN TAG#URR8PPP
Strategy for getting a “real” device time while offline
We allow users to clock-in via our react native app.
We also allow offline clock-in by saving the GEO location and timestamp of the action and waiting for an active internet connection.
Is there a way to detect whether a clever user changed the time of the device while being offline and clocking in?
We thought we could start some interval when the app last contacted the server but is it the best option? I am not sure whether an interval would properly run when the app is in the background and such.
@JonasW. I assume this is correct but we're aiming to find a way to prevent this from the average user rather than Snowden or so... ;-)
– Guy
Aug 5 at 22:11
5 Answers
5
Using Node.JS you can grab the system's uptime. See: https://nodejs.org/api/os.html#os_os_uptime
The script is os.uptime()
and returns as an integer. If they modify their clock/date this number will still keep ticking properly. You can check the delta to see if they've changed their time (note: time-zone changes may still incur naturally). If they restart their device set their current time as your new baseline and continue checking for changes from there.
os.uptime()
It doesn't prevent everything (as everything is not preventable) but sure does make it a lot harder to bypass, assuming they can figure out what your blackbox is doing.
Note:
Module: const os = require('os');
const os = require('os');
Ex Usage:
console.log(require('os').uptime())
console.log(require('os').uptime())
Are you familiar with an uptime method in React Native? It is good to learn about this NodeJS method, however, the scenario we are trying to tackle is when the app is on the darker side of the moon, aka - beyond server's reach
– Guy
Aug 5 at 22:26
@Guy As far as I can tell this should work offline? I may be missing something; I am not perfectly familiar w/ reactive native but I was under the impression Node.JS could run with it, whilst offline. If not, hope someone else can help you either way, good luck!
– Albert Renshaw
Aug 6 at 1:27
Thanks, I gave it a go but the os module is part of NodeJS and not of React Native. Someone wrote a blog post about a process for using core nodeJS modules in React Native: hackernoon.com/…. However it requires a transpiling process which will probably only work for modules with less dependencies and modules which are not device specific (such as crypto). Much appreciated.
– Guy
Aug 6 at 1:44
It's a bit tricky, instead of active checking you can do a passive checking for fraud clock-in cases.
You can run a background task which gets device time every hour or every 10 minutes and saves in a database table(say timelog_table).
Now if user changes device time and either goes in future! or in past! you will be able to see fluctuation in your timelog_table
now it's up to you that you want to process/analyse this timelog_table on device itself or on server side.
I would suggest to do it on server side, but here you will need to send this data to server.
Please ask me if you have any question/doubt.
– codemirror
Aug 5 at 17:29
That whole table isnt even necessary, he can just store the
process.uptime()
at the start of application launch and check the delta– Albert Renshaw
Aug 5 at 17:36
process.uptime()
Yes, it is clear to me and sounds solid. I will give it a try.
– Guy
Aug 5 at 22:53
Ended up using an OS ticks approach as it does not require a background task. This repository which I explored regarding using background tasks in RN mentioned it cannot guaranty the task will be fired, hence I decided to look for a different approach. The repository for background tasks: github.com/jamesisaac/react-native-background-task
– Guy
Aug 6 at 1:15
You can take Albert's answer and add another hook.
You can track the time with interval and see the changes.
Something like https://stackoverflow.com/a/3367542/2938073
The only set-back here is mobile OS's usually limit background activity...
Yes, background activity seems to be the catch. If there was some internal tick counter in RN which is unrelated to the device's date & time that would surely save the day (for us... ;-))
– Guy
Aug 5 at 22:49
If you just wanna get a "hard to fraud time":
var now = +new Date(); // or contact server
setInterval(() => now += 1000, 1000);
// Somewhen:
console.log(new Date(now));
Yes, so I wonder whether you have experience with running intervals in React Native while the app is in the background. Are they still in play?
– Guy
Aug 5 at 22:23
@guy no they won't run in background, but there a quick google turned up github.com/jamesisaac/react-native-background-task/blob/master/…
– Jonas Wilms
Aug 5 at 22:30
@guy and I'm sorry for my answer, should've read the question again before answering ... :/
– Jonas Wilms
Aug 5 at 22:32
no worries! appreciate the answer and looking at react-native-background-task. It looks it can fit incremental tasks, the docs say minimum interval time is 15 minutes, which can still act as an offline time keeper. Two things seem to make it harder to use - the fact the 15 minutes is not guaranteed and that some ticks might be dropped according to the OS's black box handling of background processes. Yet, it seems to be a useful library to know of and I will probably use it sometime soon
– Guy
Aug 5 at 22:44
I have found the following Gist which returns the number of seconds since the device booted.
With this NPM module which is based on the Gist I'm doing the following:
The only pitfall is being unable to detect the "true" time of a device which was restarted while offline. However, our PM might just decide to block offline check-ins for this scenario.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
If someone really wants to trick you out he will be able to work around every countermeasure.
– Jonas Wilms
Aug 5 at 17:10