在前端应用程序中指定 “id” 和 “created_at” 值是否不好?

huangapple go评论41阅读模式
英文:

Is it bad to specify "id" and "created_at" values within the FrontEnd app?

问题

String? id;
DateTime? created_at;

id?: string;
created_at?: Date;

我在写一个Flutter应用程序,它具有内置的空安全功能,要求我在创建时初始化变量或将其标记为可空变量,如下所示:

NodeJS TypeScript后端应用程序也需要考虑undefined类型,以免初始化变量,如下所示:

我只是想知道,是否在将这些变量插入数据库(Cassandra或MySQL)之前初始化它们,而不是让数据库自动创建这些idcreated_at变量,可以通过在表格架构中定义它们(对于MySQL),或在CQL命令中定义它们(对于Cassandra),如以下所示:
MySQL:
Cassandra:

英文:

I am writing a Flutter application that has a built-in null-safety feature requires me to initialize variables at the creation time or tag it as a nullable variable like below:

String? id;
DateTime? created_at;

Or even on my NodeJS TypeScript backend application, it needs the undefined type to be considered if we don't want to initialize the variable, like below:

id?: string;
created_at?: Date;

I am just wondering to know is it a bad idea if I initialize this variables before I insert them inside the database(Cassandra or MySQL), instead of letting the database create those id and created_at variables automatically by either defining them in TABLE schemas(for MySQL) or in a CQL command(foe Cassandra), like following:

MySQL:

  id INT AUTO_INCREMENT UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

Cassandra:

INSERT INTO table_name (id, created_at)
VALUES (uuid(), toTimestamp(now()));

答案1

得分: 1

Frontend:** 这个选项很差,甚至非常差。你基本上允许用户篡改数据。这会影响你的方式取决于你对数据的处理方式。例如,考虑这样一种情况,你提供VOD服务,用户根据观看的视频时长付费。你通过收集“我观看了XYZ的5秒”日志来进行测量。每个日志都有创建日期,然后你查询它来计算用户应付多少钱。恶意用户现在可以修改日期并将其设置为2300年,你刚刚允许用户免费观看你的内容。

另一方面,在前端设置ID,这应该是唯一的,要么非常困难,要么非常低效(还可能导致DDOS攻击)。所以你现在有了既困难又不安全的解决方案。最好不要这样做。

**更改设计:**没有设计或良好的做法应该使应用程序不安全。特别是像空安全这样基本的事情。如果它导致不安全的解决方案,那么摆脱它。或以不同的方式应用它。

接下来的两个选项都可以,各有优缺点。

(2) WebServer: 在这里设置它有一个明显的优势,那就是数据库不必处理这个。因为通常来说,扩展Web服务器比数据库更容易,这在高负载情况下可能很重要,尽管坦白说:自动增加计数器通常是一个非常快的操作。最大的缺点是,如果你想保持ID字段自动增加,那么没有一些中央支持的情况下会很困难。尽管如此,我们实际上很少需要ID自动增加。使用UUID是一种众所周知的技术,可以避免这个问题。

(3) Database: 这有一个优势,如果数据库支持的话,你可以轻松使用自动增加字段。对于MySQL来说是这样,但对于Cassandra来说不是(尽管可以模拟,你可以搜索一下)。缺点是它会减慢数据库的速度。对于MySQL来说几乎察觉不到,但对于Cassandra来说情况不同(尽管uuid()调用不会察觉到)。

时间戳可以轻松而安全地由Web服务器设置,只要你的时钟是同步的(如果你使用多台机器),并且你使用一致的时间生成/序列化方法(例如,Linux时间戳)。

我使用的经验法则是:如果我可以使用Web服务器而不是数据库来做某事,而且它不是非常困难的话,我会将它移到Web服务器。

英文:

If I understand your question correctly, there are 3 places where you can potentially set this data: frontend, webserver and database. Lets discuss each option:

(1) Frontend: This option is bad or very bad. You basically allow users to tamper the data. How this can affect you depends on what you do with the data. For example consider the situation where you have VOD service, and users pays depending on how much video they watch. You measure this by gathering "I watched 5s of XYZ" logs. Each log has created_at date, which then you query to calculate how much the user should pay. A malicious user can now modify the date and set it to, say year 2300. You've just allowed users to watch your content for free.

On the other hand setting id on the frontend, which should be unique, will be either extremely difficult or extremely inefficient (which additionally opens road for DDOS). So you have both hard and unsafe solution now. Just don't do this.

Change your design: no design or good practice should ever make the app insecure. Especially such basic things like null safety. If it leads to an insecure solution then get rid of it. Or apply it in a different way.

The next two are both ok options with advantages and disadvantages each.

(2) WebServer: setting it here has an obvious advantage that database doesn't have to do this. Since it is typically easier to scale webserver than database, it might be important under heavy load, although lets be honest: autoincrementing a counter is typically a very fast operation. The biggest disadvantage is that if you want to keep the id field autoincrementing, then it is hard without some central support. That being said, it is rarely the case that we actually need id to be autoincrementing. Using UUIDs instead is a well known technique that avoids this issue.

(3) Database: this has the advantage that you can easily use autoincrementing field, if a database supports it. This is the case for MySQL, not for Cassandra unfortunately (although it can be emulated, google it). The disadvantage is that it slows down the database. It will be barely noticable for MySQL, but for Cassandra it is a different story (although uuid() call won't be noticable).

Timestamp can be easily and safely set by webserver, as long as your clocks are synced (if you use more than one machine) and you use a consistent method of time generation/serialization (e.g. linux timestamps).

The rule of thumb that I use is: if I can do something with a webserver instead of database, and it is not insanely hard, then I will move it to the webserver.

答案2

得分: 1

在一般的网络应用中,您不能真正信任用户输入,因为用户可能生成不正确或明显恶意的输入。

无论在客户端如何生成,即使通过代码完成,都可能被用户劫持和修改。因此,经验法则是,只要求用户输入那些不能在服务器端生成的数据。

ID和时间戳可以在服务器端可靠地生成,因此我永远不会在客户端生成它们。

ID还需要是唯一的,因此在客户端生成它将非常困难。电子邮件很少用作多个表之间的ID。

英文:

In a web application in general you cannot really trust a user input as users can generate incorrect or outright malicious inputs.

Whatever you ģenerate on the client side, even if it is done via code, can be hijacked and amended by users. Therefore the rule of the thumb is that you only ask users to input those data that cannot be generated on the server side.

Ids and timestamps can be reliably generated on the server side, therefore I would never generate these on the client side.

An id also need to be unique, so it would be very difficult to gen3rate it on the client side anyway. Emails are rarely used as ids across multiple tables.

huangapple
  • 本文由 发表于 2023年2月6日 15:47:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358568.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定