Javascript React路由器v4-使用HOC的授权路由
我遇到了一个问题,无法阻止未经授权的用户访问仅授权的路由/组件,例如登录用户仪表板 我有以下代码:Javascript React路由器v4-使用HOC的授权路由,javascript,reactjs,functional-programming,react-router-v4,higher-order-components,Javascript,Reactjs,Functional Programming,React Router V4,Higher Order Components,我遇到了一个问题,无法阻止未经授权的用户访问仅授权的路由/组件,例如登录用户仪表板 我有以下代码: 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
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>
)
}
render(){
返回(
)
}
我尝试记录日志来检查是否输入了条件,但是我从render函数得到一个错误,说它无法读取null的属性
有没有办法解决我的问题,也有更好的方法来满足我的需求?只有授权用户才能严格访问特定组件警告:以下答案使用React的旧上下文API。如果您使用的是V16.3+,以下答案不适用于您 好的,根据您的逻辑,未经授权的用户被禁止访问用户组件。简单而公平。没问题 但我担心的是,您是否正在检查用户是否登录到未经身份验证的用户不应进入的组件中。我认为这是不正确的,因为:
required\u 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);
}
context
类似于props
,但它允许我们跳过
组件层次结构中的级别
因为this.context
非常容易访问和滥用,迫使我们以这种方式定义上下文
除非你真的知道自己在做什么,否则不要使用上下文。上下文的用例并不常见。阅读更多有关后果的信息
最后,在我们的HOC中,它只是将一个组件作为参数,它要么重定向到主页,要么返回我们将传递给它的组件
现在要使用它,我们在路由文件中导入HOC
import RequiredAuth from './components/auth/required_auth';
我们想要保护未经授权的用户的任何路由,我们只需按如下方式路由:
<Route path="/user" component={RequiredAuth(User)}/>
上面的行将指向主页或返回我们正在传递的组件,User
参考资料:
由于您使用的是React Router 4,Matthew Barbara的答案虽然绝对正确,但却不必要地复杂。使用RR4,您可以简单地使用重定向组件来处理重定向。有关更多信息,请参阅
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
export default function requireAuth (WrappedComponent) {
class Authentication extends Component {
render () {
if (!this.props.authenticated) {
return <Redirect to="/"/>
}
return <WrappedComponent { ...this.props }/>
}
}
function mapStateToProps (state) {
return { authenticated: state.authenticated }
}
return connect(mapStateToProps)(Authentication);
}
import React,{Component}来自“React”;
从“react redux”导入{connect};
从“react router dom”导入{Redirect};
导出默认函数requireAuth(WrappedComponent){
类身份验证扩展了组件{
渲染(){
如果(!this.props.authenticated){
返回
}
返回
}
}
函数MapStateTops(状态){
返回{authenticated:state.authenticated}
}
返回连接(MapStateTops)(身份验证);
}
理想情况下,您应该将身份验证变量设置为false,然后在componentWillMount或componentDidMount中检查条件,而不是在构造函数中检查条件,正如@Shubham Khatri所说,您不应该在构造函数中放入任何逻辑,而是使用生命周期方法。另外,要小心,您在同一个方法中同时使用了props
和this.props
。@ShubhamKhatri谢谢,添加到componentWillMount时它起作用了。我还不熟悉如何应对和了解组件的生命周期。你能展示一下路由器的代码吗?其中配置了实际路由。通常它位于main/app/index文件中。“我怀疑问题是从那里来的。@MatthewBarbara我已经在我的问题中添加了路由器的代码。路由器是浏览器路由器。另外,当我在render方法中呈现常规HTML时,将逻辑添加到ComponentMount会起作用,当我将自定义组件添加到用户组件时,它会再次失败。我是否遗漏了什么。。。当没有人发送道具时,这个HOC怎么会收到道具呢?如何获得此.props.authenticated
?mapStateToProps函数正在实现这一点我已经找到了与您相同的解决方案,关于如何使用Jest&Ezyme测试此HOC,有什么提示吗?
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
export default function requireAuth (WrappedComponent) {
class Authentication extends Component {
render () {
if (!this.props.authenticated) {
return <Redirect to="/"/>
}
return <WrappedComponent { ...this.props }/>
}
}
function mapStateToProps (state) {
return { authenticated: state.authenticated }
}
return connect(mapStateToProps)(Authentication);
}