javascript - 使用 axios 异步函数验证 React 路由
问题描述
所以我正在创建一个带有服务器(节点+快递)和客户端(cra)端的网络应用程序。根据我设置为 cookie 的 jwt 令牌验证用户时遇到问题。服务器端的验证 api 端点正常工作(用邮递员测试),但问题是返回承诺的异步检查函数,因此路由并不知道它是否经过验证,因为响应处于挂起状态。
这是服务器端的 api 端点:/api/token.js
router.get('/',
jwt({secret:'token-secret' }),
function (req,res) {
console.log(req);
if(!req.user) return res.sendStatus(401);
res.sendStatus(200);
}
)
这是客户端的 app.js: src/app.js 处理路由( /dashboard 应该只对经过验证的用户可用)
function App() {
function checkToken() {
let token = Cookies.get('Access Token')
axios.get('http://localhost:9000/api/token', {
headers: {
'Authorization': `bearer ${token}`
}
}).then(res => {
return res.status;
}).catch(err => console.log(err));
}
const handleToken = async () => {
const result = await checkToken();
return result;
}
return (
<BrowserRouter>
<Route exact={true} path='/' render={() => (
<div className="App">
<Home />
</div>
)}/>
<Route exact={true} path='/dashboard' render={() => (
<div className="App">
{console.log('checktoken log', handleToken())}
{checkToken() ? <Dashboard /> : <Login />}
</div>
)}/>
<Route exact={true} path='/login' render={() => (
<div className="App">
<Login />
</div>
)}/>
</BrowserRouter>
);
}
在这一点上,我知道也许我不应该以这种方式进行验证,因为我可能无法在渲染之前获得返回,也许它应该在生命周期钩子 componentWillMount 中完成,但我没有能够将它引入这个文件(或者一切都应该在一个完全不同的文件中完成)。
谢谢
ps 我省略了所有导入和导出默认值,因为这与这里无关
解决方案
好吧,我已经做了一些实质性的改变。首先,为了使用 history.push 我不得不重构 BrowserRouter 部分,所以现在它看起来像这个 app.js
render() {
return (
<Router history={history}>
<Route exact path='/' component={Home} />
<Route exact path='/dashboard' component={Dashboard} />
<Route exact path='/login' component={Login} />
</Router>
);
}
然后我决定不使用 api/token.js。我创建了一个高阶组件,而不是这个 api 端点,它将检查登录期间设置的 cookie。给我带来最大麻烦的部分是获取 cookie 的异步特性。这是通过 getCookie 函数中的 setTimeout 解决的,我在 componentDidMount 生命周期中调用了这个函数。
src/components/withAuth.js
state = {
data: false,
open: false,
auth: false
}
componentDidMount() {
this.getCookie();
}
getCookie(){
this.setState({
open: true,
})
setTimeout(() => {
const cookie = Cookies.get('Access Token')
if(cookie) {
this.setState({
data: true,
open: false,
auth: true
})
} else if (cookie === undefined) {
this.setState({
auth: true,
open: false
})
}
}, 700)
}
最后,为了保护路由,我用 HOC src/Views/Dashboard.js 包裹了组件
import requireAuthentication from '../components/withAuth';
class Dashboard extends Component {
render() {
return (
<div>
<DashboardContent />
</div>
);
}
}
export default requireAuthentication(Dashboard);
推荐阅读
- weblogic - Weblogic domain creating using wlst scripts
- javascript - How to write a SignalR javascript code on asp.net mvc, when we instantiate the hub on Application_Start
- logback - is there a way to use fixed-length index in logback's rolling filename pattern?
- html - Why is CSS grid showing two rows instead of one while trying to create a topnav menu? Is using grid for topnav a bad idea?
- node.js - How to set Environment variables on Google Firebase Server
- elasticsearch - Logstash - 如何更改字段类型
- c# - 我正在开发一个合并类游戏。但是碰撞问题?
- javascript - 如何向所有服务器上的频道发送消息
- php - 用于不完整 IP 地址的 REGEX
- javascript - String() 的奇怪行为