Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[[NSDate date] timeIntervalSince1970]会受系统时间影响,用CACurrentMediaTime()比较是不是好一点。 #14

Open
Vecige opened this issue May 24, 2019 · 11 comments

Comments

@Vecige
Copy link

Vecige commented May 24, 2019

[[NSDate date] timeIntervalSince1970]会受系统时间影响,用CACurrentMediaTime()比较是不是好一点。

NSTimeInterval machTime = CACurrentMediaTime(), 如果rule.lastMachTime > machTime,就用machTime比较时间间隔。否则就用NSDate比较。像这样:
image

@yulingtianxia
Copy link
Owner

@Vecige 有道理,那可以直接把 [[NSDate date] timeIntervalSince1970] 替换为 CACurrentMediaTime()

yulingtianxia added a commit that referenced this issue May 24, 2019
@Vecige
Copy link
Author

Vecige commented May 27, 2019

@yulingtianxia
直接替换有风险的。因为有做持久化,如果重启后,CACurrentMediaTime()会被重置,now = 0, now -rule.lastTimeRequest > rule.durationThreshold一直不成立。那可能这个事件永远触发不了。

@yulingtianxia yulingtianxia reopened this May 27, 2019
@yulingtianxia
Copy link
Owner

@Vecige 感觉只能只用服务器时间比较完美了。否则修改系统时间后重启 App 还是会出问题。

@Vecige
Copy link
Author

Vecige commented May 28, 2019

@yulingtianxia
我考虑重启后用NSDate的原因:重启后第一次执行该方法,用户可以手动改时间触发,然后记录的machTime就是新的了,之后再改日期能正确触发,直到再重启。如果用户遇到这个问题,能提供个简单的解决方案。

如果要持久化的话,只有用服务器时间最安全,但是都用到接口了,后端肯定自己有验证了。我没遇到过对移动端节流时间要求这么高的场景,我遇到的一般是为了减小服务端压力,避免接口并行,或者是避免push两遍。如果按照一般场景,重启后直接放行方法执行就可以了。

@yulingtianxia
Copy link
Owner

@Vecige 我觉得加个纠正时间偏移量的接口会好些,不用靠用户改时间。开发者监听系统时间变化后,将与服务器时间的偏移传进来

@Vecige
Copy link
Author

Vecige commented May 29, 2019

@yulingtianxia 嗯。这样可以。 要不要提供一个重置lastTimeRequest的方法,重启后传时间偏移量或者直接重置lastTimeRequest。

@yulingtianxia
Copy link
Owner

yulingtianxia commented May 29, 2019

@Vecige 那样太危险了,无法防止方法调用的时候修改 lastTimeRequest, 进而引发多线程问题。可以使用 alwaysInvokeBlock 在第一次返回 YES 即可。甚至,干脆不用持久化。

@Vecige
Copy link
Author

Vecige commented May 31, 2019

@yulingtianxia
提供一个纠正时间偏移量的方法确可以解决安全问题,但是使用起来并不方便,很多应用都是没有跟后台同步时间的。这需要后台提供接口或者通过HTTP Header获取时间。HTTP Header还要考虑地区、多语言的问题。

需要较严格时间校验(需要本地化),但在极端情况下(修改时间并重启),不做校验避免方法永远不能触发。 我认为这个需求还是比较常见的,应该考虑提供一种更方便的重置方法或者干脆加一个校验模式的枚举。

@yulingtianxia
Copy link
Owner

@Vecige 我觉得内部做过多逻辑反而使用很负责,因为这个问题是需要服务器时间才能解决的。如果用户断网,无法获取服务器时间,就更有可能作弊了。这个时候的策略纯属业务逻辑,可能是需要每个 App 自己定制的。而这个定制逻辑就可以写在 alwaysInvokeBlock 中,搭配服务器时间校正,可以应对这些场景了。

yulingtianxia referenced this issue Jun 3, 2019
1. 提供接口校正用户修改系统时间作弊
2. MTRule 部分属性改为只读,减少线程安全风险
@Vecige
Copy link
Author

Vecige commented Jun 15, 2019

@yulingtianxia 我还是觉得不行。点击按钮A执行logA方法,现在限制logA方法30秒内只能执行1次。用户点击按钮A触发了一次logA方法,这个时候用户再切到后台修改手机时间,然后点击按钮A又可以触发logA方法了。 除非每一次点击按钮A的时候都去跟服务器校正时间,这样真的不好。

@yulingtianxia
Copy link
Owner

@Vecige 用户修改手机时间应该会收到通知的,此时同步下服务器时间就行。一般 App 都会有获取服务器时间的接口。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants