Express与React登录认证后重定向失败问题求助
问题分析与解决方案
我明白你遇到的问题了——Passport认证成功后,浏览器居然跑去请求服务器的/secured路由,而不是React应用的,这确实让人头疼。
问题根源
你后端用的res.redirect('/secured')是关键问题:这个指令是告诉浏览器直接跳转到当前请求的服务器地址(也就是3001端口)的/secured路径,但你的Express服务器根本没配置这个路由,自然返回404。而React的路由是前端路由,运行在3000端口的应用里,后端没法直接指挥浏览器跳转到前端的路由路径。
解决方案:让前端控制路由跳转
我们需要调整前后端的交互逻辑,由后端返回认证状态,让前端自己完成路由跳转。
1. 修改Express后端的登录路由
把原来的重定向逻辑改成返回成功状态和跳转目标的JSON响应:
app.post('/login', (req, res, next) => { passport.authenticate('local', (err, user, info) => { if (err) { return next(err) } if (!user) { return res.status(401).json({ message: '登录失败,请检查用户名或密码' }) } req.logIn(user, (err) => { if (err) { return next(err) } // 不再重定向,返回成功信息和前端跳转路径 return res.status(200).json({ redirectTo: '/secured' }) }) })(req, res, next) })
2. 修改React前端的Login组件
在axios请求的回调里,利用React Router的路由能力完成跳转。因为你的代码用的是react-router-dom v5(从Route的component属性可以判断),需要通过withRouter高阶组件获取路由历史对象:
首先,在Login.js顶部导入withRouter:
import { withRouter } from 'react-router-dom'
然后修改handleSubmit方法,添加登录成功后的跳转逻辑:
handleSubmit = (event) => { event.preventDefault() axios({ method: "post", data: this.state, withCredentials: true, url: 'http://localhost:3001/login' }) .then(response => { // 登录成功,通过React Router跳转到前端路由 this.props.history.push(response.data.redirectTo) // 顺便获取用户信息 this.getData() }) .catch(error => { // 处理登录失败的情况,比如给用户提示 alert(error.response.data.message) }) }
最后,用withRouter包裹组件后导出:
export default withRouter(Login)
补充说明
- 前端路由跳转是在浏览器端完成的,不会向服务器发送请求,自然就不会出现404问题了。
- 你原来的
getData方法放在登录成功的回调里,能确保在用户认证完成后再获取用户信息,逻辑更严谨。
内容的提问来源于stack exchange,提问作者IROC
相关产品推荐
相关产品推荐

