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



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow