当前位置: 首页 > Web前端 > JavaScript

React的遮羞布

时间:2023-03-27 11:39:26 JavaScript

Vue和React是当今最流行的前端框架。当我们需要做前端项目的时候,无疑是要在两者之间选择一个自己擅长的框架来开发。当然,你也可以选择其他有自己个性的。但是选择之后,又要苦于自己的性格。我们习惯用这个框架开发PC端,比如企业官网、社交网站、电商网站、后台管理系统等等。很多时候,当我们开发一些项目比较大,内容比较多的时候,顺理成章的需要页面比较多,使用路由进行页面跳转。此时,一个新的问题出现了,如何实现路由认证呢?首先我们要搞清楚什么是路由认证。就是在页面跳转的时候验证当前用户是否有权限跳转到目标页面。这种场景其实很常见。对于稍微大一点的项目,难免会涉及到多个用户,被不同的角色使用。即便如此,一个后台管理系统,如果不登录,只能看到冰冷的登录页面。因为这个系统里面的内容太重要太敏感了。如果当前用户未通过身份验证并允许查看,那就太不安全了。一般情况下,我们的路由跳转都是通过声明式导航或者程序式导航来实现的。比如vue里面有//declarativenavigation//programmaticnavigationthis.$router.pushthis.$router.replacethis.$router.goreact有//declarativenavigation//程序化导航this.history.pushthis.history.replacethis.history.go当我们使用这些路由API时,对于各种业务需求变化,我们基本可以实现页面跳转。一般情况下,用户在使用的时候按照我们定义的路由规则是不会有任何问题的。然而,这个世界就是这么精彩,总有一些不正常的情况让我们始料未及。如果张三是一个企业的小员工,他在管理系统中的权限是只能看到A页,不能看到B页,而李四是他的上级领导,可以看到A页和B页。有一天,张三跑到李斯的办公桌跟领导商量一些事情,无意中看到了李斯电脑上B页面的内容,被迫记下了B页面的路由地址。回到工位后,脑海里不断回想刚刚看到的B页,久久不能平静。原来我们的系统里还有这么精彩的内容!于是张三灵光一闪,抬起颤抖的双手,在浏览器地址栏输入B页面的路由,点回车,新世界的大门就打开了。如果不解决这个问题,不考虑这个场景,就是我们开发人员的不专业。用户可能没有这种场景,但是我们要解决这种问题。你可以没有,但你不能没有。作为开发者,我们希望,不管用户是正常操作还是异常操作,不该重定向的不重定向,不该查看的,加个遮羞布就行了。有了目标,如何实现呢?对于vue,其实有很多解决方案,这里只举一个例子来说明。在vue中,有一个很好用的东西叫routingguard,也叫navigationguard。三类七守卫,可以指定一个回调函数。它可以在每次页面跳转的时候触发这个回调函数的执行,所以我们上面的目标就可以借助这个守卫来实现。其实vue的路由里面有一个叫做元信息的东西。就是在路由规则中增加一个叫做meta的属性。我们可以给这个meta赋一个对象,在对象里面放一个叫login的属性,如下:}}]})这个元信息也可以在routeguard中获取到。那么这个时候,我们就可以在路由守卫中进行判断了。如果当前要跳转的目标页面的路由规则中的login为true,我们认为目标页面需要路由认证。如果把当前登录用户的信息放在vuex或者其他地方,就可以获取到,获取到之后判断当前用户是否登录,是否有访问目标页面的权限。满足条件则允许,不满足则阻断。这是Vue的遮羞布。无论用户是正常操作还是重定向到异常输入的url,路由守卫都可以进行拦截和鉴权。反应呢?尤其是react-router-dom@5这个版本,它没有像vue那样的路由守卫给我们使用,也没有路由meta信息来让我们识别是否需要认证。但是这个问题很普遍,必须要解决,所以我们得自己想办法。其实玩过react的都知道react比vue更接近native,没有那么高的封装性。这意味着当框架没有为我们提供可用的功能时,我们需要自己去实现。在没有路由守卫和元信息的情况下,我们可以直接在页面中的componentDidMount语句循环函数中编写逻辑,或者在功能组件中,使用useEffect加空依赖来模拟生命周期函数。在函数中,我们可以获取到当前登录用户,假设你把登录用户保存在redux或者其他地方,现在就可以获取到。拿到之后再做判断。如果当前用户没有登录,或者当前用户没有访问该页面的权限,那么我们仍然可以使用程序化导航回退页面路由,提示用户没有访问权限。这是反应的遮羞布。当然,如果你有很多需要认证的页面。也就是说,对于一个管理系统来说,大部分的页面都应该需要这样的路由认证。这时候如果我们实现上面提到的方法区,那么每个页面都需要写很多代码,工作量大,代码冗余,而且不便于维护。我们可以想到像模拟vue路由一样,将认证代码封装到一个js文件中,把所有需要认证的页面路由地址都写在这个js文件中,我们称之为认证列表,导出module。引入需要认证的页面。通过获取当前页面的路由地址,与认证列表中的路由地址进行比较,匹配后进行认证。或者封装成高阶组件,直接包裹在原页面外等等。只要思路不滑,解决办法总是比困难多。其实这个问题也是react求职者面试时经常问到的问题。第一道题可能脑子一片空白,但如果你坐下来仔细想一想,其实并没有那么难。有react工作经验的话,几分钟就出来解决方案了。总之,react就一个字,自己动手,丰衣足食。