我无法理解为什么我的Authorized
和Unauthorized
路由运行不正常。这是我的路由设置方式:
class App extends Component {
render() {
return (
<HashRouter>
<React.Suspense fallback={loading()}>
<Switch>
<UnauthenticatedRoute exact path="/login" name="Login Page" component={Login} />
<Route exact path="/register" name="Register Page" component={Register} />
<Route exact path="/404" name="Page 404" component={Page404} />
<Route exact path="/500" name="Page 500" component={Page500} />
<AuthenticatedRoute path="/" name="Home" component={DefaultLayout} />
</Switch>
</React.Suspense>
</HashRouter>
);
}
}
export default App;
我有一个auth.js
,其中包含所有这些路由类型以及检查JWT令牌是否有效的方法:
import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { Api } from './api'
const isAuthenticated = () => {
Api.isActiveToken(sessionStorage.getItem('token')).then(
(response) => {
console.log(response)
return response.ok
},
(error) => {
return false
}
)
}
const AuthenticatedRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
isAuthenticated()
? <Component {...props} />
: <Redirect to='/login' />
)} />
);
const UnauthenticatedRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
!isAuthenticated()
? <Component {...props} />
: <Redirect to='/' />
)} />
);
export { AuthenticatedRoute, UnauthenticatedRoute }
console.log(response)
如下所示:
Response {type: "cors", url: "http://xxx/api/v1/login/validate-token", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://xxx/api/v1/login/validate-token"
__proto__: Response
我的sessionStorage
很好地持有了令牌。我在做什么错,以至于我的路线从不重定向/不允许我进入AuthorizedRoute
?
答案 0 :(得分:1)
isAuthenticated()
是异步的,当前返回void。您必须使isAuthenticated返回布尔值的承诺。
具有isAuthenticated的返回值之后,您将需要使用效果和状态将实际值从promise中拉出。
import React, { useState, useEffect } from 'react';
import { Redirect, Route } from 'react-router-dom';
import { Api } from './api';
const isAuthenticated = async () => {
try {
const response = await Api.isActiveToken(sessionStorage.getItem('token'));
return response.ok;
} catch (error) {
return false;
}
};
const AuthenticatedRoute = ({ component: Component, ...rest }) => {
const [authenticated, setAuthenticated] = useState(null);
useEffect(() => {
isAuthenticated().then((bool) => setAuthenticated(bool));
}, []);
return (
<Route
{...rest}
render={(props) => {
if (authenticated === null) return '...loading';
return authenticated ? <Component {...props} /> : <Redirect to="/login" />;
}}
/>
);
};
const UnauthenticatedRoute = ({ component: Component, ...rest }) => {
const [authenticated, setAuthenticated] = useState(null);
useEffect(() => {
isAuthenticated().then((bool) => setAuthenticated(bool));
}, []);
return (
<Route
{...rest}
render={(props) => {
if (authenticated === null) return '...loading';
return !authenticated ? <Component {...props} /> : <Redirect to="/" />;
}}
/>
);
};
export { AuthenticatedRoute, UnauthenticatedRoute };
答案 1 :(得分:0)
我认为问题在于Switch
组件需要某些类型的子组件,并且您正在向它传递它可能无法处理的其他组件类型AuthenticatedRoute
。您可以将组件转换为仅返回Route
元素的渲染函数,而不用创建新的组件类型,以便Switch
仅包含路由。
const renderAuthenticatedRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
isAuthenticated()
? <Component {...props} />
: <Redirect to='/login' />
)} />
);
const renderUnauthenticatedRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
!isAuthenticated()
? <Component {...props} />
: <Redirect to='/' />
)} />
);
class App extends Component {
render() {
return (
<HashRouter>
<React.Suspense fallback={loading()}>
<Switch>
{
renderUnauthenticatedRoute({
exact: true,
path: "/login",
name: "Login Page",
component: Login
})
}
<Route exact path="/register" name="Register Page" component={Register} />
<Route exact path="/404" name="Page 404" component={Page404} />
<Route exact path="/500" name="Page 500" component={Page500} />
{
renderAuthenticatedRoute({
path: "/",
name: "Home",
component: DefaultLayout
})
}
</Switch>
</React.Suspense>
</HashRouter>
);
}
}