我是后端编程和构建我的第一个完整堆栈项目的新手,并且是第一次使用Express / Mongoose / Mongo和Passport.js。
我已经建立了“使用Github登录”功能,并设置了Passport。现在,我想使用Redux来存储用户是否登录。如果用户已登录,我想更改导航栏,即如果用户未登录,则一个链接会显示“登录”,但是如果用户登录后,“登录”链接更改为“个人资料”。
我知道我可以在React组件中使用三元运算符来切换链接,具体取决于用户是否已登录。
如何使用Redux来存储用户是否已登录?这是我到目前为止的内容:
Redux动作:
export function loggedIn() {
return {
type: "LOGGED_IN",
loggedIn: false
}
};
Redux减速器:
export default function reducer(state = {
loggedIn: false
}, action) {
switch(action.type) {
case "LOGGED_IN": {
return {
...state,
loggedIn: true
}
}
case "LOGGED_OUT": {
return {
...state,
loggedIn: false
}
}
default: return state;
}
}
我是我的Express路线,正在使用以下中间件:
// Checks if user is not logged in
const authCheck = (req, res, next) => {
if(!req.user) {
// If user is not logged in, redirect them to login page
res.redirect('/auth/login');
}
else {
// If user is logged in call next in router.get
// Would this be the proper place to dispatch to the Redux store
// whether a user is logged in?
dispatch(loggedIn(true));
// After updating the Redux store call next()
next();
}
};
如何正确存储用户是否已登录/注销的状态,然后在React组件中访问此状态,以便我可以使用三元运算符选择在导航中显示“已登录”还是“配置文件”酒吧吗?
答案 0 :(得分:1)
建议不要将后端路由与reducer调度混合使用。我建议您在中间件中发送回信res.status(200).send({ loggedIn: true })
。
// Checks if user is not logged in
const authCheck = (req, res, next) => {
if(!req.user) {
// If user is not logged in, redirect them to login page
res.redirect('/auth/login');
}
else {
res.status(200).send({ loggedIn: true })
next();
}
};
对该中间件的调用可以根据响应调度成功。
if (res.status === 200) {
dispatch(loggedIn(res.loggedIn));
}
else {
dispatch({ type: 'LOGIN_FAILED'})
}
答案 1 :(得分:0)
您应该只在React前端中处理身份验证状态。即使您正在执行服务器端身份验证,最好还是使用Redux将身份验证状态保存在您的React前端中。在您的React应用中:
您还需要使用react-redux库来连接react和redux
动作
export const login_success = () => {
return {
type: ACTION_TYPES.LOGIN_SUCCESS
}
}
export const login_failure = () => {
return {
type: ACTION_TYPES.LOGIN_FAILURE
}
}
减速器:
const initialState = {
isAuthenticated: false,
}
const AuthReducer = (state= initialState, action) => {
switch(action.type) {
case ACTION_TYPES.LOGIN_SUCCESS:
return {
...state,
isAuthenticated: true
}
case ACTION_TYPES.LOGIN_FAILURE:
return {
...state,
isAuthenticated: false
}
}
使用道具访问身份验证状态
{this.props.isAuthenticated
? <h3> user is logged in </h3>
: <h3> user is not logged in </h3>
}
function mapStateToProps(state) {
return {
isAuthenticated: state.auth_reducer.isAuthenticated
}
}
在用户登录后呈现的回调组件中实现此功能。
function mapDispatchToProps(dispatch) {
return {
action1: () => dispatch(ACTIONS.LOGIN_SUCCESS),
}
}
如果您想了解如何执行此操作的完整示例,可以查看我构建的该项目,它是具有身份验证功能的全堆栈React Express应用程序
https://github.com/iqbal125/react-redux-fullstack-blog
为了给您一些坚强的爱,在我看来您不完全了解Redux,我建议您在尝试构建复杂的全栈应用程序之前先精通Redux,这只是一个建议。
编辑:
可以通过代理与服务器进行通信,因此可以在react应用的package.json中进行
:"proxy": http://localhost:5000"
或您的节点服务器正在运行的任何位置。您也可以将服务器响应(无论任何情况)发送回React前端,然后根据该服务器响应更新React-Redux前端。
所以在您的快递服务器中
router.get('api/login', (req, res) => {
if(res.login === true) {
res.json(success_login: true)
}
})
然后在您的反应前端
axios.get('/api/login')
.then(res => this.props.login_success(res.data) )
login_success(res) {
if(res.success_login === true) {
type: "SUCCESS_LOGIN"
}
因此,从本质上讲,您将不会在快递服务器中处理任何路由或redux身份验证状态。您的服务器将向您的React前端发送响应,然后路由和Redux身份验证状态将由您的前端处理。