【问题标题】:How to restrict access to routes in react-router-dom based on session?如何根据会话限制对 react-router-dom 中路由的访问?
【发布时间】:2020-01-02 23:18:47
【问题描述】:

我有一个使用 flask-login 的 HttpOnly Session Cookies 进行用户会话管理的 React 前端和 Python 后端。如何基于这种类型的会话管理restrict react-router-dom 路由?我创建了一个 ProtectedRoute 组件:

import { Route, Redirect } from 'react-router-dom';

class ProtectedRoute extends Component {

    constructor(props) {
        super(props);
        this.state = {
            authenticated: false,
        }
    }

    render() {
        const { component: Component, ...props } = this.props
        return (
            <Route
                {...props}
                render={props => (
                    this.state.authenticated ?
                        <Component {...props} /> :
                        <Redirect to='/login' />
                )}
            />
        )
    }
}

export default ProtectedRoute;

是否可以在现有会话的基础上设置this.setState({authenticated: true})

【问题讨论】:

    标签: reactjs react-router-dom flask-login


    【解决方案1】:

    为什么不将authenticated(或在我的示例中为isEnabled)作为道具传递? ProtectedRoute 将在其道具更改时重新渲染。这是我在 React 应用程序中使用的:

    import React from 'react';
    import { Route, Redirect } from 'react-router-dom';
    
    const ProtectedRoute = ({isEnabled, ...props}) => {
        return (isEnabled) ? <Route {...props} /> : <Redirect to="/login"/>;
    };
    
    export default ProtectedRoute;
    

    然后你可以像这样使用它:

    <ProtectedRoute path="/dashboard" isEnabled={isAuthenticated()} />
    

    【讨论】:

    • 但是 isAuthenticated() 应该怎么做呢?我找不到如何从 React 应用程序获取会话状态,而无需不断调用烧瓶 API。 Cookie 是 HttpOnly,所以我无法通过代码访问它。
    • isAuthenticated 只是会话管理中的一个函数,它根据会话是否有效返回 true 或 false。它可以检查某些 cookie 是否存在,或者 JWT 是否有效。可以是任何东西。通常,您不必一直调用 API 来检查会话。
    【解决方案2】:

    我知道这个问题很老,但我一直在寻找同样的东西。这是我的routes.js 文件:

    import auth from './services/auth'
    
    const PrivateRoute = ({isAuthenticated, ...props}) => {
      return (isAuthenticated) ? <Route {...props} /> : <Redirect to="/login"/>;
    };
    
    class Routes extends React.Component {
        constructor(){
          super();
          this.state = {
            isAuthenticated: false
          }
        }
    
        componentDidMount(){
          auth.get('')
          .then( async (response) => {
            const status = await response.status
            if (status === 200) {
              this.setState({isAuthenticated: true})
            } else {
              this.setState({isAuthenticated: false})
            }
          })
          .catch( async (error) => console.log(error))
        }
    
        render() {
          return (
            <BrowserRouter>
                <Switch>
                    <Route path="/login" exact component={Login} />
                    <PrivateRoute isAuthenticated={this.state.isAuthenticated} path="/" component={() => "barra"}/>
                    <PrivateRoute isAuthenticated={this.state.isAuthenticated} path="/home" component={() => "home"}/>
                    <PrivateRoute isAuthenticated={this.state.isAuthenticated} path="/profile" component={() => "profile"}/>
                </Switch>
            </BrowserRouter>
          )
        };
    }
    

    auth 导入是:

    const axios = require('axios');
    
    axios.defaults.withCredentials = true;
    
    const auth = axios.create({
        baseURL: "http://localhost:5000/auth"
    })
    
    export default auth;
    

    所以,基本上我有一个 Flask 应用程序,其中 Flask-Login 在另一台本地服务器上运行(启用了 CORS,这非常重要),如果返回 200,则反应用户已通过身份验证。

    【讨论】:

      猜你喜欢
      • 2015-09-14
      • 2018-06-04
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-14
      • 2020-04-14
      • 1970-01-01
      相关资源
      最近更新 更多