Статьи

Создайте приложение React.js с логином и аутентификацией пользователя.

Реальная аутентификация пользователя

Эта статья была первоначально опубликована на Stormpath . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

React (иногда его называют React.js) — это отличный способ создания веб-интерфейсов. Stormpath React SDK расширяет React и React Router маршрутами и компонентами, которые позволяют вам решать общие задачи управления пользователями с помощью Stormpath, такие как аутентификация и авторизация .

В последнее время React привлек довольно много внимания, и легко понять, почему. React позволяет вам превращать сложные пользовательские интерфейсы в простые и повторно используемые компоненты, которые можно легко составлять вместе.

В этом посте будет показано, как создать приложение React с нуля, используя Stormpath React SDK, чтобы добавить функции, позволяющие пользователям регистрироваться, входить в систему и даже просматривать свой собственный профиль пользователя.

Давайте начнем!

Стек приложений React + Express.js

Поскольку мы создаем наше приложение с нуля, мы будем использовать ES6 и JSX для написания как можно меньшего количества кода, а также Stormpath React SDK для пользовательских функций.

Чтобы дать вам хороший обзор того, что мы будем использовать:

  • Реагировать — позволяет нам создавать простые, но мощные интерфейсы.
  • ReactRouter — организует URL-навигацию в нашем приложении React.
  • ES6 — следующая версия JavaScript. Позволяет нам писать настоящие классы JavaScript.
  • JSX — позволяет размещать HTML в JavaScript без объединения строк.
  • Stormpath — позволяет нам хранить и аутентифицировать пользователей, не создавая для этого собственного бэкэнда.
  • Stormpath React SDK — без особых усилий интегрирует регистрационные формы, страницы входа и аутентификацию в наше приложение React.
  • Экспресс — позволяет нам обслуживать наши файлы HTML и JavaScript.
  • Express Stormpath — позволяет обслуживать API Stormpath через Express .
  • Webpack — позволяет нам упаковать все наши файлы JavaScript в один пакет.
  • Babel — позволяет нам переносить наши ES6 и JSX в ES5.
  • Bootstrap — потому что мы хотим, чтобы все было красиво.

Настройка нашего проекта React + Express.js

Начните с создания нового каталога проекта и файла package.json для него.

 $ mkdir my-react-app $ cd my-react-app $ npm init --yes 

Теперь установите Express, модуль Stormpath для Express и Body Parser:

 $ npm install --save express express-stormpath body-parser 

Нам нужен сервер для размещения нашего приложения, поэтому создайте новый файл с именем server.js и поместите в него приведенный ниже код:

 var express = require('express'); var stormpath = require('express-stormpath'); var bodyParser = require('body-parser'); var app = express(); app.use(stormpath.init(app, { web: { produces: ['application/json'] } })); app.on('stormpath.ready', function () { app.listen(3000, 'localhost', function (err) { if (err) { return console.error(err); } console.log('Listening at http://localhost:3000'); }); }); 

Потрясающие. Теперь мы можем подключить это к приложению Stormpath, создав новый файл с именем stormpath.yml со следующим кодом в нем. И да, вы должны заменить эти значения своими собственными.

 client: apiKey: id: YOUR_API_KEY_ID secret: YOUR_API_KEY_SECRET application: href: https://api.stormpath.com/v1/applications/XXXX <-- YOUR APP HREF 

Все идет нормально. Теперь попробуйте сервер, запустив $ node server.js . Если все настроено правильно, вы должны увидеть:

 Listening at http://localhost:3000 

Если вы увидели это сообщение, вы успешно настроили свой сервер для взаимодействия с Stormpath и предоставили REST API для использования нашим приложением React.

Настройка Webpack

Прежде чем вы будете слишком взволнованы, убейте сервер и установите Webpack, чтобы мы могли упаковать все наши клиентские сценарии (эта организация скоро понадобится нам).

 $ npm install --save webpack $ npm install --save-dev webpack-dev-middleware 

Сконфигурируйте Webpack, создав новый файл с именем webpack.config.js и вставьте в него приведенный ниже код:

 var path = require('path'); var webpack = require('webpack'); module.exports = { entry: [ './src/app' ], devtool: 'eval-source-map', output: { path: __dirname, filename: 'app.js', publicPath: '/js/' }, module: { loaders: [] } }; 

Что это будет делать, это посмотреть в нашем каталоге /src/ (который мы вскоре создадим) и упаковать все сценарии и их зависимости в этом каталоге в один модуль. Затем используйте файл /src/app.js и его экспорт в качестве экспорта этого модуля. Наконец, когда он сгенерирует этот пакет модулей, он будет обслуживать его через Express в /js/app.js точке /js/app.js .

Но для того, чтобы Express мог обслуживать файлы Webpack, нам нужно открыть server.js и добавить эти строки вверху:

 var webpack = require('webpack'); var config = require('./webpack.config'); 

Затем сразу после строки var app = express(); добавлять:

 var compiler = webpack(config); app.use(require('webpack-dev-middleware')(compiler, { noInfo: true, publicPath: config.output.publicPath })); 

Как я упоминал ранее, это позволит Webpack перехватывать запросы и обслуживать наш упакованный файл /js/app.js .

Настройка Babel

Поскольку мы будем использовать ES6 и JSX, нам нужно перенести эти файлы в ES5 (для обратной совместимости с не современными браузерами). Именно здесь приходит Babel. Babel может принимать наши файлы ES6 / JSX в качестве входных данных и конвертировать их в ES5.

Чтобы использовать Babel , начните с установки некоторых зависимостей:

 $ npm install --save babel-core babel-runtime babel-loader babel-plugin-react-transform \ babel-preset-es2015 babel-preset-react babel-preset-stage-0 

Теперь мы расскажем Babel о том, как скомпилировать наши файлы, поэтому создайте новый файл с именем `.babelrc` и добавьте в него следующий код:

 { "presets": ["stage-0", "es2015", "react"] } 

Наконец, чтобы заставить Babel работать с Webpack, нам нужно отредактировать `webpack.config.js` и добавить запись в массив` module.loaders`, как показано ниже:

 module: { loaders: [{ test: /\.js$/, loaders: ['babel'], include: path.join(__dirname, 'src') }] } 

Index.html и Bootstrap

Теперь, прежде чем мы запачкаем руки с помощью React, мы подготовим страницу входа для нашего приложения. Эта страница сообщит браузеру, что он должен загрузить, прежде чем мы инициализируем React и наше приложение. Поэтому создайте новый каталог с именем build , а затем в него поместите файл с именем index.html . Наш сервер будет обслуживать все наши статические файлы из этой папки.

 $ mkdir build $ cd build $ touch index.html 

Затем в index.html поместите следующее:

 <!doctype html> <!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]--> <!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"><![endif]--> <!--[if IE 8]><html class="no-js lt-ie9"><![endif]--> <!--[if gt IE 8]><!--> <html class="no-js"><!--<![endif]--> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <base href="/"> <title></title> <meta name="description" content=""> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="/css/bootstrap.min.css" /> </head> <body> <div id="app-container"></div> <script src="/js/app.js"></script> </body> </html> 

Кроме того, в каталоге build создайте новый каталог с именем css и загрузите в него Bootstrap . Назовите файл bootstrap.min.css .

 $ mkdir css $ cd css $ curl -O https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css $ cd ../.. # return to /my-react-app 

Теперь, чтобы наш браузер имел доступ к этим файлам, нам нужно настроить их так, чтобы они обслуживались через Express. Итак, откройте server.js и в верхней части файла добавьте:

 var path = require('path'); 

Затем под строкой app.use(stormpath.init(app, ...)); добавлять:

 app.get('/css/bootstrap.min.css', function (req, res) { res.sendFile(path.join(__dirname, 'build/css/bootstrap.min.css')); }); app.get('*', function (req, res) { res.sendFile(path.join(__dirname, 'build/index.html')); }); 

Как работает React?

Теперь, когда у нас есть скелет для нашего приложения, мы можем сосредоточиться на создании нашего приложения React. Но прежде чем писать какой-либо код, давайте посмотрим, что такое React и что он для нас делает.

Компоненты

В React все построено на компонентах. Вы можете думать о компоненте как о чем-то, что визуализирует узел DOM. Простой компонент React выглядит следующим образом:

 class HelloWorld extends React.Component { render() { return <span>Hello World!</span>; } } 

Это было просто. Теперь, если вы хотите отобразить этот компонент на странице, то все, что вам нужно сделать, это импортировать React и затем вызвать:

 ReactDOM.render( <HelloWorld />, document.getElementById('hello-world-element') ); 

И React отобразит компонент в этот элемент.

Есть, конечно, больше вещей для компонента React, таких как состояние. Ниже приведен пример компонента счетчика, который начинает отсчет при добавлении в DOM и останавливается при удалении.

 class Counter extends React.Component { state = { current: 0 } constructor() { super(arguments...); this.intervalId = null; } updateCounter() { this.setState({ counter: this.state.current + 1 }); } componentWillMount() { this.setState({ counter: this.props.from || 0 }); this.intervalId = setInterval(this.updateCounter.bind(this), 1000); } componentWillUnmount() { clearInterval(this.intervalId); } render() { return <span>{ this.state.current }</span>; } } 

Обратите внимание на методы componentWillMount() и componentWillUnmount() . Это методы жизненного цикла компонента, которые будут выполняться в различных точках жизненного цикла компонента (в данном случае — монтировать и размонтировать). Эти методы обычно используются для настройки и удаления компонента, и их необходимо использовать, потому что React выдаст ошибку, если вы попытаетесь установить состояние компонента, когда он еще не был смонтирован.

Также обратите внимание на this.props.from . Элемент this.props является коллекцией всех свойств (входных данных), передаваемых компоненту. Свойства компонента могут быть установлены, как показано ниже:

 <Counter from="50" /> <Counter from={ myVariable } /> 

Переменные JSX

Переменные можно легко вставить в JSX DOM с помощью { nameOfVariable } , например, как показано ниже:

 render() { var myVariable = 123; return <span>{ myVariable }</span>; } 

JSX и зарезервированные идентификаторы JavaScript

Поскольку JSX — это JavaScript, есть несколько предостережений, которые необходимо знать при работе с React. Т.е. при установке свойств компонента React DOM нельзя использовать ни for ни for class поскольку они считаются зарезервированными идентификаторами JavaScript. Чтобы обойти эту проблему, React предлагает htmlFor и className которые вы должны использовать вместо этого.

Чтобы проиллюстрировать проблему, это не будет работать:

 <label for="my-input" class="my-label">My Input</label> 

Но это будет:

 <label htmlFor="my-input" className="my-label">My Input</label> 

Виртуальный ДОМ

Вместо того, чтобы работать непосредственно против DOM, в React все компоненты хранятся в собственном виртуальном DOM. Вы можете думать о виртуальном DOM как о реализации DOM в JavaScript (потому что это действительно так). Этот виртуальный DOM затем отображается на реальный элемент DOM. Поэтому, когда вы визуализируете свой компонент React, React будет просматривать выходные данные DOM компонента, сравнивать его с его представлением в виртуальном DOM, а затем генерировать исправление для реального DOM.

Это означает, что вам больше никогда не придется вручную манипулировать элементами DOM. Все, что вам нужно сделать, это сказать React, как вы хотите, чтобы ваш компонент выглядел, и он позаботится о преобразовании DOM необходимыми способами (с минимальными усилиями).

Установка зависимостей React

Теперь, когда мы познакомимся с React, мы начнем с того, что установим некоторые зависимости React:

 $ npm install --save react react-dom react-router react-stormpath react-document-title history 

Прежде чем мы начнем кодировать, нам нужно место для размещения наших файлов React, поэтому создайте новый каталог с именем src , а затем используйте его в качестве рабочего каталога.

 $ mkdir src $ cd src 

Теперь давайте начнем с точки входа в наше приложение. Это будет место, где мы будем настраивать наше приложение React и его маршрутизацию. Поэтому создайте новый файл с именем app.js и введите этот код:

 import React from 'react'; import ReactDOM from 'react-dom'; import { Router, IndexRoute, Route, browserHistory } from 'react-router'; ReactDOM.render( <Router history={browserHistory}> </Router>, document.getElementById('app-container') ); 

Так что теперь у нас есть основа для нашего приложения. Давайте продолжим и импортируем Stormpath SDK и некоторые вещи, которые нам понадобятся. В верхней части файла app.js добавьте оператор импорта:

 import ReactStormpath, { Router, HomeRoute, LoginRoute, AuthenticatedRoute } from 'react-stormpath'; 

Как вы можете видеть в app.js , теперь есть два конфликтующих импорта Router . Поскольку ReactStormpath.Router расширяется от ReactRouter.Router нам больше не понадобится. Так что продолжайте и удалите импорт Router из react-router . Важно: оставьте другие импорты ReactRouter , они понадобятся нам позже.

Теперь мы инициализируем Stormpath SDK. Добавьте следующую строку прямо над ReactDOM.render() .

 ReactStormpath.init(); 

Это было легко! Теперь мы готовы начать создавать наши страницы.

Мастер страница

Прежде чем мы создадим наши страницы, мы должны настроить наш маршрутизатор. Именно маршрутизатор определяет, как мы сможем перемещаться в нашем приложении React. Мы начнем с создания общего корневого маршрута. Это будет действовать как наша «главная страница». Т.е. все маршруты по этому маршруту будут совместно использовать один и тот же главный компонент (заголовок). Поэтому поместите приведенный ниже код в <Router> в app.js чтобы он выглядел следующим образом:

 <Router history={browserHistory}> <Route path='/' component={MasterPage}> </Route> </Router> 

Как видите, мы ссылались на MasterPage . То, что еще не существует. Итак, давайте продолжим и создадим это в новом каталоге, который мы назовем pages , в нашей папке src .

 $ mkdir pages $ cd pages 

Теперь создайте новый файл с именем MasterPage.js и добавьте в него этот код:

 import React from 'react'; import { Link } from 'react-router'; import { LoginLink } from 'react-stormpath'; import DocumentTitle from 'react-document-title'; import Header from './Header'; export default class is extends React.Component { render() { return ( <DocumentTitle title='My React App'> <div className='MasterPage'> <Header /> { this.props.children } </div> </DocumentTitle> ); } } 

Как вы можете видеть, у нас еще нет компонента Header , поэтому давайте создадим новый файл с именем Header.js в том же каталоге со следующим содержимым:

 import React from 'react'; import { Link } from 'react-router'; import { LoginLink, LogoutLink, Authenticated, NotAuthenticated } from 'react-stormpath'; export default class Header extends React.Component { render() { return ( <nav className="navbar navbar-default navbar-static-top"> <div className="container"> <div id="navbar-collapse" className="collapse navbar-collapse"> <ul className="nav navbar-nav"> <li><Link to="/">Home</Link></li> </ul> <ul className="nav navbar-nav navbar-right"> </ul> </div> </div> </nav> ); } } 

Главная страница

В нашей MasterPage обратите внимание на свойство this.props.children . Он будет содержать компоненты дочерних маршрутов, которые соответствуют нашему маршрутизатору. Так что, если бы у нас был маршрут, который выглядел так:

 <Route path='/' component={MasterPage}> <Route path='/hello' component={HelloPage} /> </Route> 

И мы попытались получить доступ /hello . Массив this.props.children будет заполнен компонентом HelloPage и по этой причине этот компонент будет отображаться на нашей главной странице.

Теперь представьте сценарий, в котором вы пытаетесь получить доступ / . Без этого this.props.children будет отображаться только ваша главная страница, но с пустым содержимым. Это где IndexRoute вступает в игру. С помощью IndexRoute вы можете указать компонент, который должен отображаться при IndexRoute по пути маршрута главной страницы (в нашем случае `/`).

Но прежде чем мы добавим наш IndexRoute к нашему маршрутизатору, давайте создадим новый файл в нашем каталоге pages именем IndexPage.js и добавим в него следующее:

 import { Link } from 'react-router'; import React, { PropTypes } from 'react'; import { LoginLink } from 'react-stormpath'; export default class IndexPage extends React.Component { render() { return ( <div className="container"> <h2 className="text-center">Welcome!</h2> <hr /> <div className="jumbotron"> <p> <strong>To my React application!</strong> </p> <p>Ready to begin? Try these Stormpath features that are included in this example:</p> <ol className="lead"> <li><Link to="/register">Registration</Link></li> <li><LoginLink /></li> <li><Link to="/profile">Custom Profile Data</Link></li> </ol> </div> </div> ); } } 

Теперь давайте добавим наш IndexRoute . Откройте app.js и внутри тега <Route path='/' component={MasterPage}> добавьте свой IndexRoute чтобы он выглядел следующим образом:

 <Route path='/' component={MasterPage}> <IndexRoute component={IndexPage} /> </Route> 

Страница авторизации

Теперь у нас есть приложение React, которое показывает заголовок со страницей по умолчанию. Но у нас еще нет страницы входа. Итак, давайте создадим новый файл с именем `LoginPage.js` и добавим к нему некоторое содержимое:

 import React from 'react'; import DocumentTitle from 'react-document-title'; import { LoginForm } from 'react-stormpath'; export default class LoginPage extends React.Component { render() { return ( <DocumentTitle title={`Login`}> <div className="container"> <div className="row"> <div className="col-xs-12"> <h3>Login</h3> <hr /> </div> </div> <LoginForm /> </div> </DocumentTitle> ); } } 

Обратите внимание на компонент LoginForm . Это все, что мы должны добавить, чтобы у нас была полностью рабочая форма, в которой люди могут зарегистрироваться.

Но прежде чем мы сможем его использовать, нам нужно открыть app.js и добавить маршрут для страницы в нашем маршрутизаторе. Поэтому внутри тега <Route path='/' component={MasterPage}> добавьте следующее:

 <LoginRoute path='/login' component={LoginPage} /> 

Чтобы получить доступ к странице входа, нам нужно добавить это в наше меню. Итак, откройте Header.js и внутри элемента <ul className="nav navbar-nav navbar-right"> добавьте следующее:

 <NotAuthenticated> <li> <LoginLink /> </li> </NotAuthenticated> 

Как видите, мы используем компонент NotAuthenticated . При этом мы будем показывать LoginLink только LoginLink когда пользователь еще не вошел в систему.

Страница регистрации

Теперь давайте добавим страницу, где люди могут зарегистрироваться. Мы назовем это RegistrationPage . Поэтому создайте новый файл с именем RegistrationPage.js и поместите в него следующее содержимое:

 import React from 'react'; import DocumentTitle from 'react-document-title'; import { RegistrationForm } from 'react-stormpath'; export default class RegistrationPage extends React.Component { render() { return ( <DocumentTitle title={`Registration`}> <div className="container"> <div className="row"> <div className="col-xs-12"> <h3>Registration</h3> <hr /> </div> </div> <RegistrationForm /> </div> </DocumentTitle> ); } } 

Обратите внимание, что мы использовали компонент RegistrationForm . Как вы уже догадались, это отразит регистрационную форму Stormpath. И как только вы зарегистрируетесь, пользователи будут открывать страницу входа, где они смогут войти.

Для того, чтобы получить доступ к этой странице. Нам нужно добавить маршрут. Итак, откройте app.js и внутри тега <Route path='/' component={MasterPage}> добавьте:

 <Route path='/register' component={RegistrationPage} /> 

Теперь у нас есть маршрут, но люди не смогут найти страницу, если мы не дадим ссылку на нее, поэтому откройте Header.js и добавьте следующее прямо перед закрывающим тегом ( </ul> ) для <ul className="nav navbar-nav navbar-right"> :

 <NotAuthenticated> <li> <Link to="/register">Create Account</Link> </li> </NotAuthenticated> 

Обратите внимание на использование компонента NotAuthenticated . При этом мы будем показывать ссылку /register тогда, когда пользователь не вошел в систему.

Страница профиля

После того, как пользователь вошел в систему, мы хотим иметь возможность показывать ему некоторый персонализированный контент (его пользовательские данные). Поэтому создайте новый файл с именем ProfilePage.js и поместите в него следующий код:

 import React from 'react'; import DocumentTitle from 'react-document-title'; import { UserProfileForm } from 'react-stormpath'; export default class ProfilePage extends React.Component { render() { return ( <DocumentTitle title={`My Profile`}> <div className="container"> <div className="row"> <div className="col-xs-12"> <h3>My Profile</h3> <hr /> </div> </div> <div className="row"> <div className="col-xs-12"> <UserProfileForm /> </div> </div> </div> </DocumentTitle> ); } } 

Обратите внимание, что мы используем UserProfileForm . Это простая вспомогательная форма, которая позволяет редактировать самые основные пользовательские поля.

Хотя для того, чтобы действительно изменить профиль пользователя, нам нужно изменить несколько вещей на нашем сервере. Итак, откройте server.js и добавьте следующий маршрут под app.use(stormpath.init(app, ...)); :

 app.post('/me', bodyParser.json(), stormpath.loginRequired, function (req, res) { function writeError(message) { res.status(400); res.json({ message: message, status: 400 }); res.end(); } function saveAccount () { req.user.givenName = req.body.givenName; req.user.surname = req.body.surname; req.user.email = req.body.email; req.user.save(function (err) { if (err) { return writeError(err.userMessage || err.message); } res.end(); }); } if (req.body.password) { var application = req.app.get('stormpathApplication'); application.authenticateAccount({ username: req.user.username, password: req.body.existingPassword }, function (err) { if (err) { return writeError('The existing password that you entered was incorrect.'); } req.user.password = req.body.password; saveAccount(); }); } else { saveAccount(); } }); 

Это позволит форме изменить как имя, фамилию, адрес электронной почты, так и пароль пользователя.

Если у вас есть дополнительные поля, которые вы хотите редактировать, просто UserProfileForm форму UserProfileForm и добавьте поля, которые вы хотите редактировать, в маршрут выше.

Теперь, чтобы мы могли получить доступ к этой странице из меню, откройте Header.js и прямо под <li><Link to="/">Home</Link></li> добавьте:

 <Authenticated> <li> <Link to="/profile">Profile</Link> </li> </Authenticated> 

При этом, используя компонент Authenticated , когда у нас будет сеанс пользователя, мы отобразим ссылку на страницу /profile и позволим нашим пользователям просматривать свой профиль пользователя.

Чтобы мы могли получить доступ к странице, мы должны, как и другие страницы, добавить ее в маршрутизатор. Откройте app.js и внутри тега <Route path='/' component={MasterPage}> добавьте:

 <AuthenticatedRoute path='/profile' component={ProfilePage} /> 

Обратите внимание, что мы используем AuthenticatedRoute . Это маршрут, к которому можно получить доступ только при наличии аутентифицированного сеанса пользователя. Если сеанса нет, то пользователь будет автоматически перенаправлен на путь LoginLink .

Домашний маршрут

Теперь, когда мы настроили большую часть нашей маршрутизации. Давайте посмотрим на специальный маршрут, который называется HomeRoute . Этот маршрут сам по себе ничего не делает. Но действует как «маркер», чтобы указать, куда перенаправить при входе и выходе из системы.

Поэтому, чтобы указать, где мы хотим оказаться при выходе из системы, откройте app.js и измените:

 <Route path='/' component={MasterPage}> ... </Route> 

В:

 <HomeRoute path='/' component={MasterPage}> ... </HomeRoute> 

Теперь при выходе из системы Stormpath SDK будет знать, что он должен перенаправить на путь ‘/’. Теперь, чтобы указать, куда перенаправлять при выходе из системы, измените AuthenticatedRoute который мы создали на предыдущем шаге:

 <AuthenticatedRoute path='/profile' component={ProfilePage} /> 

Так что это выглядит так:

 <AuthenticatedRoute> <HomeRoute path='/profile' component={ProfilePage} /> </AuthenticatedRoute> 

Обратите внимание, как AuthenticatedRoute оборачивает HomeRoute . Это используется для указания аутентифицированного маршрута, который мы хотим перенаправить после входа в систему.

Выйти

Наконец, как только наши пользователи зарегистрировались и вошли в систему. Мы хотим дать им возможность выйти из системы. К счастью, добавить это действительно просто.

Итак, откройте Header.js и внутри <ul className="nav navbar-nav navbar-right"> добавьте этот код в конец:

 <Authenticated> <li> <LogoutLink /> </li> </Authenticated> 

Обратите внимание на компонент LogoutLink . После нажатия этой HomeRoute сеанс пользователя будет автоматически уничтожен, и пользователь будет перенаправлен на не прошедший проверку HomeRoute .

Состояние пользователя в компонентах

Получите доступ к пользовательской среде в ваших компонентах, запросив аутентифицированный и пользовательский типы контекста:

 class ContextExample extends React.Component { static contextTypes = { authenticated: React.PropTypes.bool, user: React.PropTypes.object }; render() { if (!this.context.authenticated) { return ( <div> You need to <LoginLink />. </div> ); } return ( <div> Welcome {this.context.user.username}! </div> ); } } 

Импорт компонентов

Чтобы иметь возможность ссылаться на наши страницы, нам нужно их импортировать. И чтобы упростить импорт, мы поместим их все вместе в файл index.js поэтому нам нужно импортировать его только один раз. Итак, давайте создадим новый файл index.js в index.js наших pages и экспортируем из него все наши страницы, как показано ниже:

 export MasterPage from './MasterPage' export IndexPage from './IndexPage' export LoginPage from './LoginPage' export RegistrationPage from './RegistrationPage' export ProfilePage from './ProfilePage' 

При этом нам нужно будет выполнить только один импорт, чтобы получить доступ ко всем нашим страницам.

Итак, давайте сделаем это. Откройте файл app.js и в верхней части файла добавьте следующий оператор импорта:

 import { MasterPage, IndexPage, LoginPage, RegistrationPage, ProfilePage } from './pages'; 

Запуск проекта

Теперь у нас есть приложение, в котором наши пользователи могут зарегистрироваться, войти в систему и показать свои пользовательские данные. Итак, давайте попробуем!

Как и раньше, запустите наш сервер, выполнив следующее:

 $ node server.js 

И если все работает успешно, вы должны увидеть это сообщение:

 Listening at http://localhost:3000 

Итак, откройте http: // localhost: 3000 в вашем браузере и попробуйте!

Резюме

Как вы видели в этой статье, React — действительно мощный инструмент, и при использовании вместе с ES6, JSX и Stormpath создание приложений снова становится забавным.

Если есть какие-то части, в которых вы не уверены, смело проверяйте пример проекта и используйте его в качестве эталонной реализации. Мне также понравился этот пост о дизайне React — в нем подробно объясняется, почему React является потрясающим.

И если у вас есть вопросы, касающиеся Stormpath React SDK , обязательно ознакомьтесь с его документацией по API .