当前位置: 首页 > 面试题库 >

React Router v4-使用HOC的授权路由

苗烈
2023-03-14
问题内容

我有一个问题要阻止未经授权的用户访问仅授权的路由/组件-例如登录的用户仪表板

我有以下代码:

import React from 'react'
//other imports
import {withRouter} from 'react-router'

class User extends React.Component {
  constructor(props) {
    super(props)
    console.log('props', props)
    let user = JSON.parse(localStorage.getItem('userDetails'))
    if(!user || !user.user || props.match.params.steamId !== user.user.steamId) {
      props.history.push('/')
    } else {
      this.props.updateUserState(user)
      this.props.getUser(user.user.steamId)
    }
  }

  //render function
}

//mapStateToProps and mapDispatchToProps

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(User))

路由器:

render() {
    return (
      <Router>
        <div>
          <Route exact path="/" component={Main}/>
          <Route path="/user/:steamId" component={User}/>
          <Route path="/completelogin" component={CompleteLogin}/>
        </div>
      </Router>
    )
  }

我尝试记录日志以检查是否已输入条件,但是从渲染函数收到错误消息,提示它无法读取null属性。

有没有办法解决我的问题,并且有更好的方法来满足我的要求?只有授权用户才能严格访问特定组件


问题答案:

警告:以下答案使用React的旧上下文API。 如果您使用的是V16.3 +,则以下答案不适用于您

好的,因此,根据您的逻辑,禁止未经授权的用户访问用户组件。简单公平。没问题。

但我担心的是,您是否正在检查用户是否登录了未经身份验证的用户不应进入的组件内部。我认为这是不正确的,因为:

  1. 这是我们程序的额外旅程-增加了不必要的效率低下。有可能我们从路由器转到“用户”组件,而“用户”组件会将我们发送回前者。乒乓。

  2. 用户组件看起来很脏。具有无关紧要的逻辑。是的,无关紧要。因为不应在用户组件中进行身份验证检查。用户组件应包含与用户相关的内容。

您认为如果不在路由器内部检查用户身份验证,而是在路由器中进行检查,您会怎么想?顾名思义,用户组件是专用于用户的,应该从那里取出检查身份验证的逻辑。

好,这很酷。 但是如何?

我们可以创建一个高阶组件(HOC),将其作为传递给它的任何组件的参数。然后,我们在HOC内添加身份验证逻辑,最后,根据我们使用的逻辑,我们可以重定向到主页或允许对给定组件的请求。

为了使HOC能够执行上述操作,它需要访问:

  1. 州。我们需要知道用户是否已登录以及状态是我们存储此类数据的位置。
  2. 路由器。我们可能需要重定向用户。

让我们命名HOC required_auth。这是它的代码:

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default function(ComposedComponent) {
    class Authentication extends Component {
        static contextTypes = {
            router: React.PropTypes.object
        }

        componentWillMount() {
            if (!this.props.authenticated) {
                this.context.router.history.push('/');
            }
        }

        componentWillUpdate(nextProps) {
            if (!nextProps.authenticated) {
                this.context.router.history.push('/');
            }
        }

        render() {
            return <ComposedComponent {...this.props} />
        }
    }

    function mapStateToProps(state) {
        return { authenticated: state.auth.authed };
    }

    return connect(mapStateToProps)(Authentication);
}

如您所见,这里没有发生黑魔法。可能令人困惑的是

static contextTypes = {
    router: React.PropTypes.object
}

context类似于,props 但是它允许我们跳过组件层次结构中的级别

由于this.context非常易于访问和滥用,因此React迫使我们以这种方式定义上下文。

*除非您真的知道自己在做什么,否则 *不要使用上下文
。上下文的用例并不常见。在此处详细了解可能的后果

总结一下我们的HOC,它只是将一个组件作为参数,然后重定向到首页或返回将传递给它的组件。

现在使用它,在路由文件中,我们导入HOC

 import RequiredAuth from './components/auth/required_auth';

以及我们想要防止未经授权的用户访问的任何路由,我们只需按以下方式进行路由:

<Route path="/user" component={RequiredAuth(User)}/>

上面的行将直接指向首页或返回我们传递的组件, User

参考: https
//facebook.github.io/react/docs/higher-order-components.html

https://facebook.github.io/react/docs/context.html


 类似资料:
  • 1.1.0版本新增了路由授权功能,采用RBAC权限管理方式实现。 每个ISV(appKey)对应一个或多个角色 每个角色分配多个路由权限 接口跟角色相关联,ISV拥有哪些角色,就具有角色对应的接口访问权限。 假设把路由a,b,c分配给了VIP角色,那么具有VIP角色的ISV可以访问a,b,c三个路由。 默认情况下,接口访问时公开的,ISV都能访问。如果要设置某个接口访问权限,在@Open注解中指定

  • 基于路径的授权 Apache和svnserve都可以给用户赋予(或拒绝)访问许可,通常是对整个版本库:一个用户可以读版本库(或不),而且他可以写版本库(或不)。如果可能,也可以定义细粒度的访问规则。一组用户可以有版本库的一个目录的读写权限,但是没有其它的;另一个目录可以是只对一少部分用户可读。 两种服务器都使用同样的文件格式描述路径为基础的规则,如果是Apache,需要加载mod_authz_sv

  • Using a delegation key The collaborator can now push to the repository using Docker Content Trust. Docker will automatically choose and pick the right key for the targets/release role. Edit the file o

  • 问题内容: 我正在将node与express和passportjs一起使用,以限制对位于私有文件夹中的文件的访问。我将代码简化为以下内容。公共静态文件夹中的所有内容都可以正常工作,但通过使用staticMiddleware定位到私有文件夹的路由将返回404错误。 我使用的以下参考似乎对其他人有用,因此我一定会丢失一些东西。这对我来说不起作用,对于私有区域中的内容仅显示404响应。 我本可以发誓我以

  • 问题内容: 在安装组件之前进行授权检查的最佳实践是什么? 我使用react-router 1.x 这是我的路线 这是我的仪表板组件: 问题答案: 更新了 React Router v4的* 解决方案 * 反应路由器到v3 使用’onEnter’事件并在回调中检查用户是否被授权:

  • 问题内容: Angular在路由上不提供任何授权/访问权限(我说的是默认的Angular路由1.x,而不是beta 2.0或UI路由)。但是我必须执行它。 我遇到的问题是我有一项服务,该服务调用服务器以提供此信息并返回承诺。但是,此数据仅获取一次,然后缓存在客户端上,但是仍然需要获取一次。 我现在想处理检查下一条路由是否定义了特定属性的事件。然后,该处理程序应使用我前面提到的服务获取该数据,并根据