反应:如果用户的cookie过期,如何注销用户?

问题描述 投票:0回答:1

背景:在快速后端上,我正在使用快速会话来分配用户会话。在React前端,我具有适当的功能来防止用户输入受保护的路由。不过,有一个麻烦的极端情况:如果经过身份验证的用户在应用程序中保留足够长的时间以使其cookie过期,那么他们将可以自由地访问所有经过身份验证的路由,称为“幽灵”(也就是没有cookie)和不正确的状态:this.state.isAuthenticated = true是,从技术上来说,它们的状态是“经过身份验证的”,因为它们从未注销或重新安装了该组件,从而阻止了我获取后端并执行检查,因此这就是为什么我将它们称为“鬼”

为什么?嗯,每次安装我的App组件时,请确保检查用户状态。如果他们通过了身份验证阶段,那么我的后端将为他们提供会话,并且我将身份验证状态设置为true。因为我的应用程序组件永远不会重新安装,所以当用户遍历我的应用程序时,他们将能够以“幽灵”身份访问未经授权的路由。

Caveat:如果它们偶然在任何时候刷新或按注销按钮,则我的组件将重新安装,并删除其访问权限,因为它们不是合法用户。

我希望我已经做好了我的处境。我的问题是:如果Cookie过期,我该如何删除用户?

Edit:我在Protectedroute.js中有一个可行的解决方案,但是除非用户离开页面,否则checkAuth()的调用次数是无限的。 我想避免Redux,因为我一周前才开始使用React

ProtectedRoute.js

function ProtectedRoute({component: Component}, {...rest}) {
    return(
    <userContext.Consumer>
        {({isAuthenticated, checkAuth}) => {
            checkAuth()
            return  <Route {...rest} render = {(props) => isAuthenticated ? (<Component {...props}/>) : (<Redirect to ='/login' />)} />
        }}
    </userContext.Consumer>
    )
}

App.js

class App extends Component {
    constructor(props, context) {
        super(props, context)

        this.state = {
            isAuthenticated: false,
            isLoading: true
        }

        this.handleLoggedIn = this.handleLoggedIn.bind(this)
        this.handleLoggedOut = this.handleLoggedOut.bind(this)
        this.isAuthenticated = this.isAuthenticated.bind(this)
    }

    componentDidMount() {
        //Get and set currently logged in user
        //console.log('--componentDidMount--')
        this.isAuthenticated()
    }


    isAuthenticated() {
        const url = 'http://localhost:9000/api/auth'
        fetch(url, {
            method: 'GET',
            credentials: 'include',
            headers: {
                'Content-Type' : 'application/json'
            }
        })
        .then((response) => response.text())
        .then((data) => {
            //console.log(data)
            if (data === 'true') {
                console.log('--isAuthenticated--')
                this.setState({
                    isAuthenticated: true,
                    isLoading: false
                })
            } else {
                this.setState({
                    isAuthenticated: false,
                    isLoading: false
                })
            }
        })
        .catch((err) => {
            console.log('Error', err)
        })
    }

    handleLoggedIn() {
        console.log('--handleLoggedIn--')
        this.setState({
            isAuthenticated: true
        })
    }

    handleLoggedOut() {
        this.setState({
            isAuthenticated: false
        })

    }

    render() {
        const value = {
            loggedIn: this.handleLoggedIn,
            loggedOut: this.handleLoggedOut,
            isAuthenticated: this.state.isAuthenticated,
            checkAuth: this.isAuthenticated
        }

        if (this.state.isLoading) {
            return(<div>LOADING</div>)
        } else {
            return (
                <Router>
                    <userContext.Provider value = {value}>
                        <div>
                            <userContext.Consumer>
                                {(value) => (<Navigation isAuthenticated = {this.state.isAuthenticated} />)}
                            </userContext.Consumer>
                        </div>
                        <Switch>
                            <Route path = '/signup'>
                                <Signup />
                            </Route>
                            <Route path = '/login'>
                                <Login handleLoggedIn={this.handleLoggedIn}/>
                            </Route>
                            <Route path = '/feed'>
                                <Feed />
                            </Route>
                            <Protectedroute path = '/create-post' component={CreatePost} />
                        </Switch>
                    </userContext.Provider>
                </Router>
            )
        }
    }
}
javascript reactjs redux react-router-dom reactjs-flux
1个回答
0
投票

您可以创建一个fetchWrapper,它将调用所有提取API到您的后端。每当您检测到从前端接收的cookie过期时,请发送401响应代码。在fetchWrapper中侦听401,并在遇到401时重新加载页面以登录路由。您的问题可能有多种解决方案,这就是其中之一。


0
投票

很好地使用setTimeout是检查n时间间隔内cookie过期时间的方法。

[如果您不想使用setInterval的另一种方法是,您可能想开发一种方法,以便检查每个安全请求的cookie,然后检查该请求状态代码是否返回了401您的服务器,则可能会显示模式显示your session is expired, click here to login...

© www.soinside.com 2019 - 2024. All rights reserved.