Поиск…


Вступление

В этом документе будет показано, как использовать ReactRouter с Meteor и React. От нуля до рабочего приложения, включая роли и аутентификацию.

Я покажу каждый шаг с примером

1- Создать проект

2- Add React + ReactRouter

3- Добавить учетные записи

4- Добавить пакеты ролей

Создать проект

1- Сначала установите https://www.meteor.com/install

2. Создайте проект. ( --bare - создать пустой проект)

meteor create --bare MyAwesomeProject

3- Создайте минимальную структуру файла ( -p для создания промежуточных каталогов):

cd MyAwesomeProject

mkdir -p client server imports/api imports/ui/{components,layouts,pages} imports/startup/{client,server}

4 Теперь создайте файл HTML в файле 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- Убедитесь, что он работает: (3000 - это порт по умолчанию, поэтому вы можете пропустить «-p 3000»)

meteor run -p 3000

и открытие вашего браузера на «localhost: 3000»

Замечания:

  • Я пропускаю некоторые другие файлы, которые вам нужно создать, чтобы сделать вещи короче. В частности, вам нужно будет создать некоторые файлы index.js в клиенте , import / startup / {client, server} и серверных каталогах.

  • Вы можете просмотреть полный пример в https://github.com/rafa-lft/Meteor_React_Base . Найдите тег Step1_CreateProject

Добавить React + ReactRouter

При необходимости перейдите в каталог проекта cd MyAwesomeProject

1- Добавить реактивный и реактивный маршрутизатор

meteor npm install --save [email protected] [email protected] [email protected]

2- Измените client / main.html и замените контент:

 <body>
    <div id="react-root"></div>
 </body>

Независимо от того, что решает реактор, он покажет его в элементе «# response-root»

3- Создайте файл макетов в импорте / 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- Создать файл маршрутов в импорте / запуске / клиенте / 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')
  );
});

Замечания:

  • Я пропускаю некоторые другие файлы, которые вам нужно создать, чтобы сделать вещи короче. В частности, проверьте импорт / ui / pages {Index.jsx, NotFound.jsx}.

  • Вы можете просмотреть полный пример в https://github.com/rafa-lft/Meteor_React_Base . Найдите тег Step2_ReactRouter

Шаг 3. Добавление учетных записей

При необходимости перейдите в каталог проекта cd MyAwesomeProject

1- Добавление пакетов учетных записей: meteor add accounts-base accounts-password react-meteor-data

2- Добавьте маршруты для входа и регистрации в импорте / запуске / Routes.jsx. Метод render () будет выглядеть следующим образом:

  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>
    );
  }

Замечания:

  • Я пропущу некоторые другие файлы, которые вам понадобятся, чтобы сделать вещи короче. В частности, проверьте импорт / startup / server / index.js import / ui / layouts / {App, NavBar} .jsx и import / ui / pages / {Вход, регистрация, пользователи, EditUser} .jsx

  • Вы можете просмотреть полный пример в https://github.com/rafa-lft/Meteor_React_Base . Искать тег Step3_Accounts

Добавить роли

1- Добавить пакет ролей ( https://github.com/alanning/meteor-roles)

meteor add alanning:roles

2- Создайте несколько констант ролей. В файлах импорта / api / accounts / role.js

const ROLES = {
  ROLE1: 'ROLE1',
  ROLE2: 'ROLE2',
  ADMIN: 'ADMIN'
};

export default ROLES;

3- Я не буду показывать, как добавлять / обновлять роли для пользователя, просто упомянем, что на стороне сервера вы можете установить роли пользователя с помощью Roles.setUserRoles(user.id, roles); Проверьте дополнительную информацию в https://github.com/alanning/meteor-roles и http://alanning.github.io/meteor-roles/classes/Roles.html.

4- Предполагая, что вы уже настроили все файлы учетных записей и ролей (см. Полный пример в https://github.com/rafa-lft/Meteor_React_Base . Ищите тег Step4_roles ), теперь мы можем создать метод, который будет отвечать за разрешение ( или нет) доступ к различным маршрутам. В импорте / запуске / клиенте / 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>
    );
  }
}

Мы добавили триггер onEnter для некоторых маршрутов. Для этих маршрутов мы также передаем, какие роли разрешены для входа. Обратите внимание, что обратный вызов onEnter изначально получает 2 параметра. Мы используем частичное выражение underscore ( http://underscorejs.org/#partial) , чтобы добавить еще один (роли). Метод аутентификации (вызываемый onEnter) получает роли и:

  • Убедитесь, что пользователь вошел в систему. Если нет, перенаправляется на '/ login'.
  • Если роли === '*', мы предполагаем, что любой зарегистрированный пользователь может войти, поэтому мы разрешаем это
  • Кроме того, мы проверяем, разрешен ли пользователь (Roles.userIsInRole), а если нет, мы перенаправляем на запрещенный.
  • При желании вы можете раскомментировать строку, поэтому ADMIN имеет доступ ко всему.

В коде есть несколько примеров различных маршрутов, которые разрешены для кого-либо (без обратного вызова onEnter), для любого зарегистрированного пользователя, для любого зарегистрированного пользователя с хотя бы одной ролью и для определенных ролей.

Также обратите внимание, что ReactRouter (по крайней мере, на версии 3) не позволяет модифицировать маршруты на Render. Таким образом, вы не можете скрыть маршруты в Routes.jsx. По этой причине мы перенаправляем / запрещаем метод аутентификации.

5- Общая ошибка с ReactRouter и Meteor, относится к обновлениям статуса пользователя, которые не отображаются. Например, пользователь вышел из системы, но мы все еще показываем его имя на навигационной панели. Это происходит потому, что Meteor.user () изменился, но мы не перерисовываем.

Эта ошибка может быть решена путем вызова Meteor.user () в createContainer. Вот пример этого, используемый в импорте / 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);

Замечания:

  • Я пропущу некоторые другие файлы, которые вам понадобятся, чтобы сделать вещи короче. В частности, проверьте импорт / startup / server / index.js import / ui / layouts / {App, NavBar} .jsx и import / ui / pages / {Вход, регистрация, пользователи, EditUser} .jsx

  • Вы можете просмотреть полный пример в https://github.com/rafa-lft/Meteor_React_Base . Искать метки Step4_roles



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow