首页 > 解决方案 > 使用 axios 删除用户令牌后重定向无法正常登录页面

问题描述

我正在尝试让我的网站做 3 件事:

  1. 在用户登录并从 API 接收用户令牌后,我将其存储在 sessionStorage 中。所以如果 sessionStorage.getItem('userToken'),用户将被重定向到主页。

  2. 如果用户已登录,则不允许用户返回登录页面再次登录。因此,如果用户尝试转到 /login,他将被重定向到主页。

  3. 如果用户注销,他的令牌将从 sessionStorage 中删除,他将被重定向到登录页面。

如果我不在 header.js 中使用 axios 注销,它可以工作,但如果我将 sessionStorage.removeItem("userToken") 放在 axios 中,它就不起作用。用户将被重定向到主页如果他们在标题中单击注销,只有当我刷新页面时,他们才会被重定向到登录页面。

所以我觉得问题是:只有当我从后端获得删除成功响应时,才会执行 sessionStorage.removeItem 部分。但是只有在执行removeItem时,页面才会因为PrivateRoute部分而被重定向,所以我觉得delete=> removeItem是异步的,而removeItem => PrivateRoute部分是同步的,但是在登录页面中不知何故,因为if(sessionStorage.getItem ('userToken')) { return () } ,它仍然可以获得 userToken 所以它仍然重定向到家

我该如何解决?太感谢了!

header.js

logout = () => {


        const auth = sessionStorage.getItem('userToken');
        const url = `http://xxxxxx/users/sign_out`;
        // sessionStorage.removeItem("userToken"); This works..
        axios.delete(url, {
            params: { id: auth }
        }).then(res => {
            sessionStorage.removeItem("userToken");//This not work


        }).catch(err => {
            console.log(err);

        })

登录.js

 constructor() {
        super();

        this.state = {
            redirect: false

        };
    }
......

render() {

        if (this.state.redirect) {
            return (<Redirect to={'/'} />)
        }

        if (sessionStorage.getItem('userToken')) {
            return (<Redirect to={'/'} />)
        }
        return (
    <Formik
onSubmit={(values, { setSubmitting }) => {
                                setSubmitting(true);
                                axios.post('xxx/users/sign_in', {
                                    user: {
                                        email: values.email,
                                        password: values.password
                                    }
                                }).then(res => {


                                    sessionStorage.setItem('userToken', res.data.auth_token);

                                    this.setState({ redirect: true });
                                }).catch(err => {
                                    console.log(err);
                                    alert('wrong email address or password');
                                    setSubmitting(false);
                                })

                            }}

......
......
)}

PrivateRoute.js

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={(props) => (
        sessionStorage.getItem('userToken') ? <><Header /> <Component {...props} /></> : <Redirect to="/sign-in" />
    )} />
)

应用程序.js

<Switch>
            <PrivateRoute exact path="/" component={Home}>
            </PrivateRoute>
            <PrivateRoute exact path="/management" component={Management}>
            </PrivateRoute>




            <Route exact path="/sign-up" component={SignUpForm}>
            </Route>
            <Route exact path="/sign-in" component={SignInForm}>
            </Route>

            <Route component={Error}>
            </Route>
          </Switch>

标签: javascriptreactjsreact-router-dom

解决方案


发生这种情况是因为放入sessionStorage.removeItem("userToken");axios 回调是异步的,而sessionStorage.removeItem("userToken");直接放入 logout 方法是同步的。

因此,当用户在单击注销后被重定向到主页时,userToken仍然存在 sessionStorage。因为axios的回调函数还没有执行,所以还在等待回调函数的响应。

要解决此问题,请尝试在 axios 回调函数本身中重定向到主页。这确保当用户到达主页时,userToken从会话存储中删除。


推荐阅读