检查用户是否已支付订阅费用的最佳方法是什么? 我想检查用户是否按月付费,否则,我将把他重定向到付款页面。
我的解决方案 :
使用JWT :每当用户登录时,我将next_payment_date
(从databse检查)写入jwt并签名。因此,每次用户请求受保护的路由(只有付费用户才能访问的路由)时,我都会解码令牌并检查next_payment_date
并采取相应的行动
此方法的问题:假设用户正在使用手机和计算机。在计算机中,他收到付款过期通知,并且成功付款。 但稍后,当他使用电话时,他的电话将不会更新**jsonwebtoken**
,这将使他重定向到付款页面(这不是一个好兆头)
解决方案2:
始终从数据库检查付款状态。
此问题:每次请求到来时,都应该查询数据库,这是无用的读取操作。
如果您知道任何更好/有效的方法来解决此问题,请建议我
答案 0 :(得分:2)
第三种解决方案是使用某些内存服务,例如Redis。
内存中服务将按原样存储数据(在内存中),而CRUD操作将比数据库操作快得多。
因此,解决方案是:
始终检查付款状态
但是将其存储在Redis中。
在这种情况下,您需要在操作时更新用户的付款状态。
您可以将用户付款状态保存为布尔值,并在付款时对其进行更新。
要删除付款状态,您可以使用EXPIRE键(在付款步骤中进行设置),然后Redis将从内存中删除用户付款。
如果您的应用程序确实很大,并且您想真正提高内存效率,请阅读有关EXPIRE here和here的更多信息,然后选择它是否对您有用。
注意:另外,在JWT的情况下,用户可以更改它,因此,如果您完全信任JWT,则用户可以欺骗您。 JWT还有更多可能的问题,您可以阅读here
[更新]:
关于在评论中提到的MongoDB。
正如您在解决方案2中所说的“ ...这是无用的读取操作。”,在您的案例数据库中,每个有状态服务都是有状态的。
这意味着它必须将数据保存在某处。对于此任务数据库,请使用磁盘。
不管是SQL还是NoSQL数据库,它都必须从磁盘上读取/写入数据。意味着需要更多时间和资源。
另一方面,内存中服务将数据存储在内存中,这意味着代码不需要进入数据库,不需要在磁盘上查找数据,等待db在磁盘上查找数据然后返回给用户。 />
内存存储只是在内存中查找数据,这是非常快的。您可以阅读here来了解更多信息。
底线,内存中存储比任何数据库都快。
但是,像往常一样,解决方案取决于您的任务。
如果您需要创建测试服务,或者每秒要处理约100个请求,那么有状态数据库就足够了。
但是,如果您需要加快代码速度或处理更多负载,最好使用内存存储。