Я изо всех сил пытаюсь определить лучший способ обработки аутентификации в моем приложении стека React / React-Router / Redux / MERN-stack, и любая помощь приветствуется. В частности, я не очень хорошо объединяю различные библиотеки, и в результате я обрабатываю проверку, если пользователь вошел в систему на уровне отдельных компонентов, хотя я думаю, что это должно быть сделано в App.js.
Мое приложение использует для аутентификации passport.js, а у моего mongodb есть коллекция users
, которая отслеживает информацию о каждом пользователе. Документ в коллекции users
выглядит следующим образом:
Мое приложение имеет действие с избыточностью userActions
, которое использует authorizedReducer
для добавления к reduxState объектов один или несколько из userInfo, authorized, loading
. loading
просто возвращает ИСТИНА / ЛОЖЬ в зависимости от того, завершено ли действие, authorized
возвращает логическое ИСТИНА / ЛОЖЬ относительно того, зарегистрирован ли пользователь, , если авторизовано == ИСТИНА , тогда userInfo
возвращает информацию о пользователе из документа mongodb (в противном случае userInfo
не возвращается).
С учетом всего сказанного он определяет структуру моих файлов App.js и index.js:
App.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import AppNavbar from './components//Navbars/AppNavbar';
import LoginModal from './components/LoginModal';
import SignupModal from './components/SignupModal';
import HomePage from './path-to-component';
import AboutUs from './path-to-component';
import HelpPage from './path-to-component';
import NoMatch from './path-to-nomatch';
... import of ~15 other routes ...
// Want to use this redux userAction to get info on the user (if he's logged in, other acct info, etc.)
import { userActions } from '../../../actions/auth/auth-actions.js';
class App extends Component {
constructor(props, context) {
super(props, context);
this.handleShowLogin = this.handleShowLogin.bind(this);
this.handleCloseLogin = this.handleCloseLogin.bind(this);
this.handleShowSignup = this.handleShowSignup.bind(this);
this.handleCloseSignup = this.handleCloseSignup.bind(this);
this.state = {
showLogin: false,
showSignup: false
};
}
// dont worry about these - just used for displaying login / signup modals
handleCloseLogin() { this.setState({ showLogin: false }); }
handleShowLogin() { this.setState({ showLogin: true }); }
handleCloseSignup() { this.setState({ showSignup: false }); }
handleShowSignup() { this.setState({ showSignup: true }); }
// want to be able to do 1-time grab of user actions, storing the user's info in reduxstate
componentDidMount() {
this.props.dispatch(userActions.authorize());
}
render() {
return (
<React.Fragment>
<AppNavbar login={this.handleShowLogin} signup={this.handleShowSignup} />
<LoginModal close={this.handleCloseLogin} showLogin={this.state.showLogin} signup={this.handleShowSignup} />
<SignupModal close={this.handleCloseSignup} showSignup={this.state.showSignup} />
<Switch>
<Route exact path='/' render={(props) => <HomePage {...props} />} />
<Route exact path='/about' render={(props) => <AboutUs {...props} />} />
<Route exact path='/site-guide' render={(props) => <HelpPage />} />
... ~15 more routes ...
<Route component={NoMatch} />
</Switch>
<AppFooter />
<TableHeaderTooltip/>
</React.Fragment>
);
}
}
// want to have this here to grab userInfo & authorized, but this doesnt work in App.js
function mapStateToProps(reduxState) {
return {
userInfo: reduxState.authorizedReducer.userInfo,
authorized: reduxState.authorizedReducer.authorized,
loading: reduxState.authorizedReducer.loading
};
}
export default connect(mapStateToProps)(App);
index.js
import store from './store';
... other imports ...
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById('root'));
Короче говоря, вышеупомянутый App.js не работает как задумано. UserInfo и авторизованный пользователь не работают, и мне интересно, нельзя ли выполнить избыточную выборку данных в файле App.js.
В итоге было бы здорово получить информацию об аутентификации (пользователь вошел в систему и, если да, что информация о пользователе) в основном файле App.js. Я хочу передать логический authorizedReducer.authorized
и объект userInfo
в качестве реквизитов в маршруты. Вместо этого, в настоящее время я вызываю userActions () для получения информации userInfo / auth, но это вызывается в каждом компоненте, который нуждается в этой информации (например, HomePage и About, но также во многих маршрутах моих приложений, которые исключены выше (... ) нужны userInfo и авторизованная информация).
Возможно ли это? Я двигаюсь по правильному пути или я должен идти в другом направлении? Любая помощь с этим очень ценится !!
РЕДАКТИРОВАТЬ: если это поможет - это то, что мой reduxState выглядит как w.r.t. соответствующие редукторы для авт. У меня есть authentication
редуктор, который проверяет вход в систему, а затем authorizedReducer
редуктор, который также проверяет вход в систему, а также имеет userInfo.
EDIT2: , чтобы уточнить, редуктор authentication
автоматически заполняется значением TRUE, когда пользователь вошел в систему, и это здорово. Однако userInfo
и authorized
из authorizedReducer
заполняются только при отправке действия userActions()
.