Ricerca…
introduzione
Questo documento mostrerà come usare ReactRouter con Meteor e React. Da zero a un'app funzionante, inclusi ruoli e autenticazione.
Mostrerò ogni passaggio con un esempio
1- Crea il progetto
2- Aggiungi React + ReactRouter
3- Aggiungi account
4- Aggiungere pacchetti Roles
Crea il progetto
1- Prima di tutto, installa https://www.meteor.com/install
2- Creare un progetto. ( --bare
è creare un progetto vuoto)
meteor create --bare MyAwesomeProject
3- Creare la struttura di file minima ( -p
per creare directory intermedie):
cd MyAwesomeProject
mkdir -p client server imports/api imports/ui/{components,layouts,pages} imports/startup/{client,server}
4- Ora, crea un file HTML in client / main.html
<head>
<meta charset="utf-8">
<title>My Awesome Meteor_React_ReactRouter_Roles App</title>
</head>
<body>
Welcome to my Meteor_React_ReactRouter_Roles app
</body>
5- Assicurati che funzioni: (3000 è la porta predefinita, quindi puoi saltare la "-p 3000")
meteor run -p 3000
e aprendo il browser su "localhost: 3000"
Nota:
Sto saltando alcuni altri file che è necessario creare, per rendere le cose più brevi. In particolare, è necessario creare alcuni file index.js nelle directory client , importazioni / avvio / {client, server} e server .
È possibile visualizzare un esempio completo in https://github.com/rafa-lft/Meteor_React_Base . Cerca tag Step1_CreateProject
Aggiungi React + ReactRouter
Se necessario, passare alla directory del progetto cd MyAwesomeProject
1- Aggiungi reagire e reagire-router
meteor npm install --save [email protected] [email protected] [email protected]
2- Modifica client / main.html e sostituisci il contenuto sarà:
<body>
<div id="react-root"></div>
</body>
Qualunque cosa il reactRouter decida di mostrare, lo mostrerà nell'elemento '# react-root'
3- Creare il file di layout in import / ui / layouts / App.jsx
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
App.propTypes = {
children: PropTypes.node
};
export default App;
4- Creare il file Routes in importazioni / startup / client / Routes.jsx
import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import App from '../../ui/layouts/App.jsx';
import NotFound from '../../ui/pages/NotFound.jsx';
import Index from '../../ui/pages/Index.jsx';
class Routes extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Router history={ browserHistory }>
<Route path="/" component={ App }>
<IndexRoute name="index" component={ Index }/>
<Route path="*" component={ NotFound }/>
</Route>
</Router>
);
}
}
Routes.propTypes = {};
Meteor.startup(() =>{
ReactDOM.render(
<Routes/>,
document.getElementById('react-root')
);
});
Nota:
Sto saltando alcuni altri file che è necessario creare, per rendere le cose più brevi. In particolare, controlla le importazioni / ui / pages {Index.jsx, NotFound.jsx}.
È possibile visualizzare un esempio completo in https://github.com/rafa-lft/Meteor_React_Base . Cerca tag Step2_ReactRouter
Passaggio 3: aggiungere account
Se necessario, passare alla directory del progetto cd MyAwesomeProject
1- Aggiungere pacchetti di account: meteor add accounts-base accounts-password react-meteor-data
: meteor add accounts-base accounts-password react-meteor-data
2- Aggiungi i percorsi per accedere e registrare le pagine in importazioni / startup / Routes.jsx Il metodo render () sarà il seguente:
render() {
return (
<Router history={ browserHistory }>
<Route path="/" component={ App }>
<IndexRoute name="index" component={ Index }/>
<Route name="login" path="/login" component={ Login }/>
<Route name="signup" path="/signup" component={ Signup }/>
<Route name="users" path="/users" component={ Users }/>
<Route name="editUser" path="/users/:userId" component={ EditUser }/>
<Route path="*" component={ NotFound }/>
</Route>
</Router>
);
}
Nota:
Sto saltando alcuni altri file che ti serviranno per rendere le cose più brevi. In particolare, controlla importazioni / startup / server / index.js import / ui / layouts / {App, NavBar} .jsx e importa / ui / pagine / {Login, Registrati, Utenti, EditUser} .jsx
È possibile visualizzare un esempio completo in https://github.com/rafa-lft/Meteor_React_Base . Cerca tag Step3_Account
Aggiungi ruoli
1- Aggiungi pacchetto ruoli ( https://github.com/alanning/meteor-roles)
meteor add alanning:roles
2- Creare alcune costanti di ruoli. Nel file imports / api / accounts / roles.js
const ROLES = {
ROLE1: 'ROLE1',
ROLE2: 'ROLE2',
ADMIN: 'ADMIN'
};
export default ROLES;
3- Non mostrerò come aggiungere / aggiornare i ruoli su un utente, dirò solo che sul lato server, è possibile impostare i ruoli utente da Roles.setUserRoles(user.id, roles);
Controlla maggiori informazioni in https://github.com/alanning/meteor-roles e http://alanning.github.io/meteor-roles/classes/Roles.html
4- Supponendo che tu abbia già configurato tutti i file account e ruoli (vedi esempio completo in https://github.com/rafa-lft/Meteor_React_Base . Cerca tag Step4_roles ) ora possiamo creare un metodo che sarà incaricato di consentire ( oppure no) accesso ai diversi percorsi. In importazioni / avvio / client / Routes.jsx
class Routes extends Component {
constructor(props) {
super(props);
}
authenticate(roles, nextState, replace) {
if (!Meteor.loggingIn() && !Meteor.userId()) {
replace({
pathname: '/login',
state: {nextPathname: nextState.location.pathname}
});
return;
}
if ('*' === roles) { // allow any logged user
return;
}
let rolesArr = roles;
if (!_.isArray(roles)) {
rolesArr = [roles];
}
// rolesArr = _.union(rolesArr, [ROLES.ADMIN]);// so ADMIN has access to everything
if (!Roles.userIsInRole(Meteor.userId(), rolesArr)) {
replace({
pathname: '/forbidden',
state: {nextPathname: nextState.location.pathname}
});
}
}
render() {
return (
<Router history={ browserHistory }>
<Route path="/" component={ App }>
<IndexRoute name="index" component={ Index }/>
<Route name="login" path="/login" component={ Login }/>
<Route name="signup" path="/signup" component={ Signup }/>
<Route name="users" path="/users" component={ Users }/>
<Route name="editUser" path="/users/:userId" component={ EditUser }
onEnter={_.partial(this.authenticate, ROLES.ADMIN)} />
{/* ********************
Below links are there to show Roles authentication usage.
Note that you can NOT hide them by
{ Meteor.user() && Roles.userIsInRole(Meteor.user(), ROLES.ROLE1) &&
<Route name=.....
}
as doing so will change the Router component on render(), and ReactRouter will complain with:
Warning: [react-router] You cannot change <Router routes>; it will be ignored
Instead, you can/should hide them on the NavBar.jsx component... don't worry: if someone tries to access
them, they will receive the Forbidden.jsx component
*************/ }
<Route name="forAnyOne" path="/for_any_one" component={ ForAnyone }/>
<Route name="forLoggedOnes" path="/for_logged_ones" component={ ForLoggedOnes }
onEnter={_.partial(this.authenticate, '*')} />
<Route name="forAnyRole" path="/for_any_role" component={ ForAnyRole }
onEnter={_.partial(this.authenticate, _.keys(ROLES))}/>
<Route name="forRole1or2" path="/for_role_1_or_2" component={ ForRole1or2 }
onEnter={_.partial(this.authenticate, [ROLES.ROLE1, ROLES.ROLE2])} />
<Route name="forRole1" path="/for_role1" component={ ForRole1 }
onEnter={_.partial(this.authenticate, ROLES.ROLE1)}/>
<Route name="forRole2" path="/for_role2" component={ ForRole2 }
onEnter={_.partial(this.authenticate, ROLES.ROLE2)} />
<Route name="forbidden" path="/forbidden" component={ Forbidden }/>
<Route path="*" component={ NotFound }/>
</Route>
</Router>
);
}
}
Abbiamo aggiunto un trigger onEnter ad alcune rotte. Per quelle rotte, passiamo anche a quali ruoli è permesso entrare. Si noti che il callback onEnter, riceve inizialmente 2 parametri. Stiamo usando il partial del underscore ( http://underscorejs.org/#partial) , per aggiungerne un altro (ruoli) Il metodo di autenticazione (chiamato da onEnter) riceve i ruoli e:
- Controlla se l'utente ha effettuato l'accesso. In caso contrario, reindirizza a "/ login".
- Se i ruoli === '*' supponiamo che qualsiasi utente connesso possa entrare, quindi lo permettiamo
- Altrimenti, verifichiamo se l'utente è autorizzato (Roles.userIsInRole) e in caso contrario reindirizziamo su proibito.
- Facoltativamente, puoi decommentare una riga, in modo che ADMIN abbia accesso a tutto.
Il codice contiene diversi esempi di percorsi diversi consentiti per chiunque (nessun callbackEntro on), per qualsiasi utente registrato, per qualsiasi utente registrato con almeno un ruolo e per ruoli specifici.
Si noti inoltre che ReactRouter (almeno nella versione 3) non consente di modificare i percorsi su Render. Quindi non puoi nascondere i percorsi all'interno di Routes.jsx. Per questo motivo, reindirizziamo a / vietato nel metodo di autenticazione.
5- Un bug comune con ReactRouter e Meteor, si riferisce agli aggiornamenti dello stato dell'utente che non vengono mostrati. Ad esempio, l'utente si è disconnesso, ma stiamo ancora mostrando il suo nome sulla barra di navigazione. Ciò accade perché Meteor.user () è cambiato, ma non stiamo ri-rendering.
Questo bug può essere risolto chiamando Meteor.user () in createContainer. Ecco un esempio di esso, utilizzato in import / ui / layouts / NavBar.jsx:
export default createContainer((/* {params}*/) =>{
Meteor.user(); // so we render again in logout or if any change on our User (ie: new roles)
const loading = !subscription.ready();
return {subscriptions: [subscription], loading};
}, NavBar);
Nota:
Sto saltando alcuni altri file che ti serviranno per rendere le cose più brevi. In particolare, controlla importazioni / startup / server / index.js import / ui / layouts / {App, NavBar} .jsx e importa / ui / pagine / {Login, Registrati, Utenti, EditUser} .jsx
È possibile visualizzare un esempio completo in https://github.com/rafa-lft/Meteor_React_Base . Cerca tag Step4_roles