翻译 Meteor React 制作 Todos - 10 - 方法的安全性

方法的安全性

在这个步骤之前,这款应用的任何用户都可以修改数据库的任何部分,在一个非常有意思的小项目或者演示项目中可能已经不错了,但是任何一个真实的应用都需要对这些数据进行权限控制。
在Meteor上,最好的方法就是通过声明方法。以此来直接取代客户端的代码。这些方法叫做insert,update,还有remove,这将会替换执行的方法。它将会确认用户是否有权限完成这么一整套操作。那么随后在客户端中做出的任何对客户端的改变都会发给数据库

移除 insecure

每一个新创建的Meteor项目都被默认的添加了insecure包。这个包允许我们从客户端中编辑数据库。在做产品原型的时候这个包非常的有用,但是现在我们得关掉这个备胎。要移除这个包,我们得去应用目录下执行

meteor remove insecure

如果在移除这个包之后你试着去使用这款应用,你将会看到输入框或者是按钮都不能用了,这是因为所有的客户端数据库的权限被取消了,现在我们需要在我们的应用中通过使用一些方法来重写一些部分

定义一些方法

首先我们需要定义一些方法,我们需要一个方法,这个方法为我们定义了每个数据库想在客户端执行的所有操作。这些方法应该用代码定义,可以同时在客户端和服务端执行 -- 我们会晚点儿在标题为“乐观的界面”的章节中继续讨论

// simple-todos-react.jsx文件

    React.render(<App />,document.getElementById("render-target"));
  });
}

// 添加开始
Meteor.methods({
  addTask(text) {
    // 在插入之前确保用户已经登陆
    if (! Meteor.userId()) {
      throw new Meteor.Error("not-authorized");
    }
 
    Tasks.insert({
      text: text,createdAt: new Date(),owner: Meteor.userId(),username: Meteor.user().username
    });
  },removeTask(taskId) {
    Tasks.remove(taskId);
  },setChecked(taskId,setChecked) {
    Tasks.update(taskId,{ $set: { checked: setChecked} });
  }
});
// 添加结束

现在我们定义了我们的一些方法。我们需要去更新一些地方。我会要用刚刚定义好的方法去操作数据库,而不是默认的。

// App.jsx文件中

// 通过React的ref属性来找到文本的字段
var text = React.findDOMNode(this.refs.textInput).value.trim();

// 添加开始
Meteor.call("addTask",text);
// 添加结束

// Clear form
React.findDOMNode(this.refs.textInput).value = "";
// Tasks.jsx文件中
 
toggleChecked() {
  // 设置确认值为当前属性的相反值
  // 添加下一行
  Meteor.call("setChecked",this.props.task._id,! this.props.task.checked);
},deleteThisTask() {

    // 添加下面一行
  Meteor.call("removeTask",this.props.task._id);
},render() {

现在,我们的输入和按钮又能用了,我们从这些工作中收获了什么呢?

  1. 当我们向数据库插入数据的时候,现在我们已经可以安全的验证用户是否登录,createdAt字段是不是正确,ownerusername字段是不是正确。一个用户不能模仿任何人了。

  2. 当用户想让任务成为隐私性质的时候。我们可以在后面的步骤中给setCheckeddeleteTask添加额外的验证逻辑

  3. 我们的客户端代码和数据库逻辑更加的分离了。取代了许多在事件监听被触发的时候的杂事。现在我们有了可以在任何地方被调用的一些方法。

乐观的UI

那么我们为什么要在服务端和客户端定义我们自己的方法呢。我们做这些是为了开启一个我们称之为“乐观的UI”的特性。

当我们在客户端嗲用Meteor.call方法的时候,在这个时间点将会发生两件事情。

  1. 客户端向服务器端发送一个在安全环境下的请求。就像是AJAX那样的运行的请求。

  2. 一个方法模拟器直接会在客户端运行。它试图通过已有的信息来预测服务端返回的结果

这就意味着来自后端(服务器端)的结果到达客户端之前,新创建的任务已经实际地在屏幕上展现出来了。

如果从服务端返回的结果和在客户端模拟的结果一致,一切仍然像之前所展现的一样。
如果从服务端返回的结果和在客户端模拟的结果不一致,那么界面将会补充上来自服务端的真实状态的反应。

掌握了Meteor的一些“方法定义”和”乐观的UI“,你就得到了两个世界的精髓 -- 服务端代码的安全保护和无传输延迟(no round-trip delay)。阅读blog post about optimistic UI可以了解更多这方面的知识

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom