react 身份证校验校验_使用用户身份验证构建React应用

萧英睿
2023-12-01

react 身份证校验校验

React is an awesome way to build web UIs. This JavaScript library allows you to turn complex UIs into simple and reusable components that can be composed easily together. This post will show you how to build a React application from scratch, using the Stormpath React SDK to add features that allow people to sign up, login, and even view their own user profile.

React是构建Web UI的一种很棒的方法。 此JavaScript库使您可以将复杂的UI转换为可以轻松组合在一起的简单且可重用的组件。 这篇文章将向您展示如何使用Stormpath React SDK从零开始构建React应用程序,并添加允许人们注册,登录甚至查看自己的用户个人资料的功能。

Let's get started!

让我们开始吧!

You'll first need to create a Stormpath account and application, which you can do here: https://api.stormpath.com/register

首先,您需要创建一个Stormpath帐户和应用程序,您可以在此处执行以下操作: https ://api.stormpath.com/register

安装React + Express.js应用程序堆栈 ( Install the React + Express.js Application Stack )

Since we're building our application from scratch, we'll use ES6 and JSX to write as little code as possible, as well as the Stormpath React SDK for user features.

由于我们是从头开始构建应用程序,因此我们将使用ES6JSX编写尽可能少的代码,以及用于用户功能的Stormpath React SDK

Here's an overview of what we'll be using:

这是我们将使用的概述:

  • React - Allows us to compose simple yet powerful UIs.

    React-允许我们编写简单但功能强大的UI。
  • ReactRouter - Organizes the URL navigation in our React application.

    ReactRouter-在我们的React应用程序中组织URL导航。
  • ES6 - The next version of JavaScript. Allows us to write real JavaScript classes.

    ES6 -JavaScript的下一版本。 允许我们编写真正JavaScript类。
  • JSX - Allows us to place HTML in JavaScript without concatenating strings.

    JSX-允许我们将HTML放置在JavaScript中而无需连接字符串。
  • Stormpath - Allows us to store and authenticate users without having to create our own backend for it.

    Stormpath-允许我们存储和验证用户,而无需为其创建自己的后端。
  • Stormpath React SDK - Integrates Stormpath into our React application with very little effort.

    Stormpath React SDK-只需很少的努力即可将Stormpath集成到我们的React应用程序中。
  • Express - Allows us to serve our HTML and JavaScript files.

    Express-允许我们提供HTML和JavaScript文件。
  • Express Stormpath - Allows us to serve Stormpath's API through Express.

    Express Stormpath-允许我们通过Express服务于Stormpath的API。
  • Webpack - Allows us to pack all of our JavaScript files into one bundle.

    Webpack-允许我们将所有JavaScript文件打包到一个捆绑包中。
  • Babel - Allows us to transpile our ES6 and JSX into ES5.

    巴别塔 -允许我们transpile我们ES6和JSX到ES5。
  • Bootstrap - Because we want things to be pretty.

    Bootstrap-因为我们希望事情变得漂亮。

设置React + Express.js项目 ( Set up the React + Express.js Project )

Start by creating a new project directory and a package.json file for it.

首先创建一个新的项目目录和一个package.json文件。

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

Now install Express and the Stormpath module for Express:

现在安装Express和Express的Stormpath模块:

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

We need a server to host our application, so create a new file named server.js and put the code below in it:

我们需要一个服务器来承载我们的应用程序,因此创建一个名为server.js的新文件,并将下面的代码放入其中:

var express = require('express');
var stormpath = require('express-stormpath');

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

Awesome. Now we can hook that up to a Stormpath Application by creating a new file named stormpath.yml with the following code in it. And yeah, you do have to replace those values in it with your own.

太棒了 现在,我们可以通过使用以下代码创建一个名为stormpath.yml的新文件,将其连接到Stormpath应用程序。 是的,您必须用自己的值替换其中的那些值。

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

So far so good. Now try the server by running $ node server.js. If everything is set up correctly then you should see:

到目前为止,一切都很好。 现在,通过运行$ node server.js尝试服务器。 如果一切设置正确,则应该看到:

Listening at http://localhost:3000

If you saw that message, you've successfully configured your server to talk with Stormpath and expose a REST API for our React application to use.

如果看到该消息,则说明您已成功配置服务器以与Stormpath进行通信,并公开了REST API供我们的React应用程序使用。

配置Webpack (Configuring Webpack)

Before you get too excited, kill the server and install Webpack so that we can package all of our client-side scripts (we'll need this organization soon).

在您太兴奋之前,请终止服务器并安装Webpack,以便我们可以打包所有客户端脚本(我们很快将需要此组织)。

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

Configure Webpack by creating a new file named webpack.config.js and put the code below in it:

通过创建一个名为webpack.config.js的新文件来配置Webpack ,并将以下代码放入其中:

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: []
  }
};

What this will do is look in our /src/ directory (that we'll create shortly) and package all of the scripts and their dependencies under that directory as one module. Then use the file /src/app.js and its exports as the export of that module. Then finally when it has generated that module package, it will serve that through Express under the /js/app.js endpoint.

要做的就是查看我们的/src/目录(我们将很快创建),并将所有脚本及其依赖项打包到该目录下,作为一个模块。 然后,将文件/src/app.js及其导出用作该模块的导出。 最后,当它生成该模块包时,它将通过Express/js/app.js端点下提供该/js/app.js

But in order for Express to serve webpack files, we have to open up server.js and add these lines to the top of it:

但是为了使Express能够提供webpack文件,我们必须打开server.js并将这些行添加到它的顶部:

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

Then immediately after the line var app = express(); add:

然后紧接在行var app = express(); 加:

var compiler = webpack(config);

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

As I mentioned before, this will allow Webpack to intercept requests and serve our packaged /js/app.js file.

如前所述,这将允许Webpack拦截请求并提供打包的/js/app.js文件。

配置Babel (Configuring Babel)

Since we'll be using ES6 and JSX, we need to transpile these files into ES5 (for backwards compatibility with non-modern browsers). This is where Babel comes in. Babel can take our ES6/JSX files as input, and convert those to ES5.

由于我们将使用ES6和JSX,因此我们需要将这些文件转换为ES5(以与非现代浏览器向后兼容)。 这就是Babel的用处。Babel可以将我们的ES6 / JSX文件作为输入,并将其转换为ES5。

To use Babel, start by installing some dependencies:

要使用Babel ,请先安装一些依赖项:

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

Now we'll instruct Babel on how to compile our files, so create a new file named .babelrc and add this code it:

现在,我们将指导Babel如何编译文件,因此创建一个名为.babelrc的新文件,并添加以下代码:

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

Finally, in order to get Babel to work with Webpack, we need to edit webpack.config.js and add an entry to the module.loaders array, as shown below:

最后,为了使Babel使用Webpack,我们需要编辑webpack.config.js并向module.loaders数组添加一个条目,如下所示:

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

Index.html和Bootstrap (Index.html and Bootstrap)

Now, before getting our hands dirty with React, we'll prepare the entry page for our app. This page will tell the browser what it must load before we initialize React and our application. So create a new directory named build, then within that, put a file named index.html. Our server will serve all of our static files from this folder.

现在,在开始使用React之前,我们将为我们的应用程序准备输入页面。 该页面将告诉浏览器在初始化React和应用程序之前必须加载什么。 因此,创建一个名为build的新目录,然后在其中放入名为index.html的文件。 我们的服务器将提供此文件夹中的所有静态文件。

$ mkdir build
$ cd build
$ touch index.html

Then within index.html, put the following:

然后在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>

Also, under the build directory, create a new directory named css and download Bootstrap to it. Name the file bootstrap.min.css.

另外,在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

Now in order for our browser to be able to access these files we need to configure them so that they are served through Express. So open up server.js and at the top of the file add:

现在,为了使我们的浏览器能够访问这些文件,我们需要对其进行配置,以便通过Express进行提供 。 因此,打开server.js并在文件顶部添加:

var path = require('path');

Then under the line app.use(stormpath.init(app, ...)); add:

然后在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如何工作? ( How Does React Work? )

Now that we have the skeleton for our app done, we can focus on building our React app. But before we write any code, let's take a look at what React is and what it does for us.

现在我们已经完成了应用程序的框架,我们可以专注于构建React应用程序。 但是在编写任何代码之前,让我们看一下React是什么以及它对我们有什么作用。

组件 (Components)

In React, everything is built upon components. You can think of a component as something that renders a DOM node. A simple React component looks like this:

在React中,一切都建立在组件上。 您可以将组件视为呈现DOM节点的组件。 一个简单的React组件如下所示:

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

That was simple. Now, if you wanted to render this component to a page, then all you'd have to do is import React and then call:

那很简单。 现在,如果您想将此组件呈现到页面上,那么您要做的就是导入React,然后调用:

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

And React would render the component to that element.

然后React将组件渲染到该元素。

There are, of course, more things to a React component, such as state. Below is an example of a counter component that starts counting when added to the DOM and stops when removed.

当然,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>;
  }
}

Notice the methods componentWillMount() and componentWillUnmount(). These are component life-cycle methods that will be executed at various points of a component's life-cycle (in this case, mount and unmount). These methods are usually used for setting up and tearing down a component and is necessary to use because React will error if you try to set the state of a component when it hasn't been mounted yet.

注意方法componentWillMount()componentWillUnmount() 。 这些是组件生命周期方法,将在组件生命周期的各个点(在这种情况下为安装和卸载)执行。 这些方法通常用于设置和拆卸组件,并且是必须使用的,因为如果在尚未安装组件时尝试设置组件的状态,React将会出错。

Also notice this.props.from. The member this.props is a collection of all the properties (inputs) passed to a component. Properties of a component can be set as shown below:

另请注意this.props.from 。 成员this.props是传递给组件的所有属性(输入)的集合。 可以如下设置组件的属性:

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

JSX变量 (JSX Variables)

Variables can easily be interpolated into your JSX DOM using { nameOfVariable }, e.g. as shown below:

可以使用{ nameOfVariable }轻松将变量插入到您的JSX DOM中,例如,如下所示:

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

JSX和保留JavaScript标识符 (JSX and Reserved JavaScript Identifiers)

Since JSX is JavaScript, there are some caveats that you need to know when working with React. I.e. when setting properties of a React DOM component you cannot use neither for or class since those are considered reserved JavaScript identifiers. To get around this problem, React has come up with htmlFor and className that you should use instead.

由于JSX是JavaScript,因此在使用React时需要了解一些注意事项。 即设置的属性时作出ReactDOM组件,你不能既使用forclass ,因为这些被认为是预留JavaScript标识符。 为了解决这个问题,React提供了htmlForclassName ,您应该使用它。

To illustrate the issue, this won't work:

为了说明问题,这将不起作用:

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

But this will:

但这将:

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

虚拟DOM (Virtual DOM)

Instead of working directly against the DOM, in React all components are kept in their own virtual DOM. You can think of the virtual DOM as a DOM implementation in JavaScript (because it actually is). This virtual DOM is then mapped to a real DOM element. So when you render your React component, React will look at the DOM output from the component, compare it to its representation in the virtual DOM, and then generate a patch for the real DOM.

在React中,不是直接针对DOM,而是将所有组件都保存在自己的虚拟DOM中。 您可以将虚拟DOM视为JavaScript中的DOM实现(因为实际上是这样)。 然后将此虚拟DOM映射到实际DOM元素。 因此,当您渲染React组件时,React将查看该组件的DOM输出,将其与虚拟DOM中的表示形式进行比较,然后为实际DOM生成补丁。

What this means is that you never have to think of manually manipulating DOM elements again. All you have to do is tell React how you want your component to look like, and it will take care of transforming the DOM the ways necessary (with minimal effort).

这意味着您不必再考虑手动操作DOM元素。 您所要做的就是告诉React您希望组件的外观如何,它将负责以必要的方式(最小的工作量)来转换DOM。

安装React依赖 (Installing React Dependencies)

Now when we are acquainted with React, we'll kick things off by installing some React dependencies:

现在,当我们熟悉了React时,我们将通过安装一些React依赖项来开始:

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

Before we start coding, we need a place to put our React files, so create a new directory named src, and then use that as your working directory.

在开始编码之前,我们需要一个放置React文件的地方,因此创建一个名为src的新目录,然后将其用作您的工作目录。

$ mkdir src
$ cd src

Now, let's start with the entry point of our app. This will be the place where we will set up our React application and its routing. So create a new file named app.js and enter this code:

现在,让我们从应用程序的入口开始。 这将是我们设置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')
);

So now we have a foundation for our application. Let's go ahead and import the Stormpath SDK and some things we'll need in it. At the top of your app.js file, add the import statement:

因此,现在我们为应用程序奠定了基础。 让我们继续并导入Stormpath SDK和其中需要的一些东西。 在app.js文件的顶部,添加导入语句:

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

As you can see in app.js there's now two conflicting Router imports. Since ReactStormpath.Router extends from ReactRouter.Router we won't be needing that anymore. So go ahead and remove the Router import from react-router. Important: Leave the other ReactRouter imports, we'll be needing those later.

如您在app.js看到的,现在有两个相互冲突的Router导入。 由于ReactStormpath.Router从延伸ReactRouter.Router我们将不会需要再这样了。 因此,继续并从react-router删除Router导入。 重要提示: 剩下其他的ReactRouter导入,稍后我们将需要它们。

Now, we'll initialize the Stormpath SDK. Add the following line right above ReactDOM.render().

现在,我们将初始化Stormpath SDK。 在ReactDOM.render()上方添加以下行。

ReactStormpath.init();

That was easy! We're now ready to start building our pages.

那很简单! 现在,我们准备开始构建页面。

母版页 ( Master Page )

Before we create our pages, we have to set up our router. The router is what determines how we'll be able to navigate around in our application. We'll start by creating a shared root route. This will act as our "master page". I.e. all routes under this route will all share the same master component (header). So place the codebelow inside the <Router> tag in your app.js so that it looks like:

在创建页面之前,我们必须设置路由器。 路由器决定了我们如何在应用程序中导航。 我们将从创建共享根路由开始。 这将充当我们的“母版页”。 即,该路由下的所有路由都将共享相同的主组件(标头)。 因此,将下面的代码放在app.js<Router>标记内,使其看起来像:

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

As you can see, we have referenced MasterPage. Something that doesn't exist yet. So let's go ahead and create that in a new directory that we'll name pages, in our src folder.

如您所见,我们引用了MasterPage 。 尚不存在的东西。 因此,让我们继续在新目录中创建该目录,并将其命名为src文件夹中的pages

$ mkdir pages
$ cd pages

Now create a new file named MasterPage.js and add this code to it:

现在创建一个名为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>
    );
  }
}

As you can see, we don't have a Header component yet, so let's go and create a new file named Header.js in the same directory with the following content:

如您所见,我们还没有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>
    );
  }
}

索引页 ( Index Page )

In our MasterPage notice the property this.props.children. This will contain the components of the child routes that our router match. So if we had a route that looked like:

在我们的MasterPage注意属性this.props.children 。 这将包含我们路由器匹配的子路由的组成部分。 因此,如果我们有一条看起来像的路线:

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

And we tried to access /hello. The this.props.children array would be populated with a HelloPage component and for that reason that component would be rendered in our master page.

并且我们尝试访问/hello 。 将使用HelloPage组件填充this.props.children数组,因此该组件将在我们的母版页中呈现。

Now imagine the scenario where you try to access /. Without any this.props.children, this would only render your master page but with empty content. This is where IndexRoute comes into play. With an IndexRoute you can specify the component that should be rendered when you hit the path of the master page route (in our case /).

现在想象一下您尝试访问/的场景。 没有任何this.props.children ,这只会呈现您的母版页,但内容为空。 这就是IndexRoute发挥作用的地方。 使用IndexRoute您可以指定当您点击母版页路径(在我们的示例中为/ )时应该呈现的组件。

But before we add our IndexRoute to our router, let's create a new file in our pages directory named IndexPage.js and add the following to it:

但是,我们添加我们之前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>
    );
  }
}

Now let's add our IndexRoute. Open up app.js and inside the tag <Route path='/' component={MasterPage}> add your IndexRoute so that it looks like the following:

现在,让我们添加IndexRoute 。 打开app.js并在标签<Route path='/' component={MasterPage}>添加您的IndexRoute ,使其类似于以下内容:

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

登录页面 ( Login Page )

We now have an application that shows a header with a default page. But we don't have any place to login yet. So let's create a new file named LoginPage.js and add some content to it:

现在,我们有了一个显示带有默认页面标题的应用程序。 但是我们还没有登录的地方。 因此,让我们创建一个名为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>
    );
  }
}

Notice the LoginForm component. This is all we have to add in order for us to have a fully working form in which people can sign up from.

注意LoginForm组件。 这是我们要添加的全部内容,以便我们拥有可以供人们注册的完整工作表格。

But before we can use it, we need to open up app.js and add a route for the page in our router. So inside the tag <Route path='/' component={MasterPage}> add the following:

但是在使用它之前,我们需要打开app.js并在路由器中为该页面添加路由。 因此,在标记<Route path='/' component={MasterPage}>添加以下内容:

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

In order to be able to access the login page, we need to add this to our menu. So go ahead and open up Header.js and inside the element <ul className="nav navbar-nav navbar-right"> add the following:

为了能够访问登录页面,我们需要将其添加到菜单中。 因此,继续打开Header.js并在元素<ul className="nav navbar-nav navbar-right">添加以下内容:

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

As you can see we're using the NotAuthenticated component. With this we'll only show a LoginLink when the user isn't logged in yet.

如您所见,我们正在使用NotAuthenticated组件。 这样,我们将仅在用户尚未登录时显示LoginLink

注册页面 ( Registration Page )

Now, let's add a page where people can sign up. We'll call it RegistrationPage. So create a new file named RegistrationPage.js and put the following content in it:

现在,让我们添加一个页面,供人们注册。 我们将其称为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>
    );
  }
}

Notice that we used the RegistrationForm component. As you might have guessed, this will render a Stormpath registration form. And once you've signed up it will point users to the login page where they'll be able to login.

注意,我们使用了RegistrationForm组件。 您可能已经猜到了,这将呈现一个Stormpath注册表格。 注册后,它将使用户指向登录页面,他们将可以登录。

In order to access this page. We need to add a route. So go ahead and open up app.js and inside the tag <Route path='/' component={MasterPage}> add:

为了访问此页面。 我们需要添加一条路线。 因此,继续打开app.js并在<Route path='/' component={MasterPage}>标记内添加:

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

We now have a route, but people won't be able to find the page unless we link to it, so open up Header.js and add the following right before the closing tag (</ul>) of <ul className="nav navbar-nav navbar-right">:

现在,我们有了一条路线,但是除非我们链接到该页面,否则人们将无法找到该页面,因此请打开Header.js并在<ul className="nav navbar-nav navbar-right">的结束标记( </ul> )之前添加以下内容<ul className="nav navbar-nav navbar-right">

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

Notice the use of the NotAuthenticated component. With this we'll only show the /register link when the user isn't logged in.

请注意,使用了NotAuthenticated组件。 这样,我们只会在用户未登录时显示/register链接。

个人资料页 ( Profile Page )

Once a user is logged in, we want to be able to show them some personalized content (their user data). So create a new file named ProfilePage.js and put the following code in it:

用户登录后,我们希望能够向他们显示一些个性化内容(他们的用户数据)。 因此,创建一个名为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>
    );
  }
}

Notice that we use the UserProfileForm. This is a simple helper form that allows you to edit the most basic user fields.

注意,我们使用了UserProfileForm 。 这是一个简单的帮助程序表单,允许您编辑最基本的用户字段。

Though, in order to actually modify the user profile, we need to change a few things in our server. So open up server.js, add var bodyParser = require('body-parser'); to the top of the file and then add the following route underneath app.use(stormpath.init(app, ...));:

但是,为了实际修改用户个人资料,我们需要在服务器中进行一些更改。 因此,打开server.js ,添加var bodyParser = require('body-parser'); 到文件顶部,然后在app.use(stormpath.init(app, ...));下添加以下路由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();
  }
});

This will allow the form to change both the given name, surname, email and password of user. If you have additional fields that you wish to edit, then simply customize the UserProfileForm form and add the fields that you wish to edit in the route above.

这将允许表单更改用户的给定名称,姓氏,电子邮件和密码。 如果您还有其他要编辑的字段,则只需自定义UserProfileForm表单,然后在上面的路由中添加要编辑的字段。

Now, in order for us to access this page from the menu, open up Header.js and right below <li><Link to="/">Home</Link></li> add:

现在,为了使我们能够从菜单访问此页面,请打开Header.js然后在<li><Link to="/">Home</Link></li>下方添加:

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

With this, using the Authenticated"(https://github.com/stormpath/stormpath-sdk-react/blob/master/docs/api.md#authenticated) component, when we have a user session we'll render a link to the /profile page and allow our users to view their user profile.

这样,使用Authenticated “(( https://github.com/stormpath/stormpath-sdk-react/blob/master/docs/api.md#authenticated )组件,当我们进行用户会话时,我们将呈现一个链接/profile页面,并允许我们的用户查看其用户个人资料。

In order for us to be able to access the page, we must as with the other pages add it to the router. Open up app.js and inside the tag <Route path='/' component={MasterPage}> add:

为了使我们能够访问该页面,我们必须像其他页面一样将其添加到路由器中。 打开app.js并在<Route path='/' component={MasterPage}>标记内添加:

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

Notice that we're using AuthenticatedRoute. This is a route that can only be accessed if there is an authenticated user session. If there's no session, then the user will automatically be redirected to the path of the LoginLink.

注意,我们正在使用AuthenticatedRoute 。 这是只有经过身份验证的用户会话才能访问的路由。 如果没有会话,则用户将自动重定向到LoginLink的路径。

本国路线 ( Home Route )

Now when we've setup most of our routing. Let's look at a special route called the HomeRoute. This route itself doesn't do anything. But acts as a "marker", to indicate where to redirect to when logging in and logging out.

现在,当我们设置完大部分路由之后。 让我们看一下称为HomeRoute的特殊路由。 这条路线本身没有任何作用。 但是充当“标记”,以指示登录和注销时重定向到的位置。

So in order to specify where we want to end up when we log out, open up app.js and change the:

因此,为了指定退出时要在哪里结束,请打开app.js并更改:

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

Into:

进入:

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

Now when logging out, the Stormpath SDK will know that it should redirect to the '/' path. Now, to specify where to redirect when logging out, change the AuthenticatedRoute that we created in the previous step:

现在注销时,Stormpath SDK将知道它应该重定向到“ /”路径。 现在,要指定注销时重定向到的位置,请更改我们在上一步中创建的AuthenticatedRoute

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

So that it looks like:

这样看起来像:

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

Notice how the AuthenticatedRoute wraps the HomeRoute. This is used to indicate the authenticated route that we want to redirect to after login.

注意AuthenticatedRoute如何包装HomeRoute 。 这用于指示登录后我们要重定向到的经过身份验证的路由。

登出 ( Logout )

Finally, once our users have signed up and logged in. We want to give them the option to logout. Fortunately, adding this is really simple.

最后,一旦我们的用户注册并登录。我们希望为他们提供注销选项。 幸运的是,添加它确实很简单。

So open up Header.js and inside <ul className="nav navbar-nav navbar-right"> add this code to the end:

因此,打开Header.js并在<ul className="nav navbar-nav navbar-right">添加以下代码:

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

Notice the LogoutLink component. Once this is clicked, the user session will be automatically destroyed and the user will be redirected to the unauthenticated HomeRoute.

注意LogoutLink组件。 单击此选项后,用户会话将被自动破坏,并且用户将被重定向到未经HomeRoute验证的HomeRoute

组件中的用户状态 ( User State in Components )

Access user state in your components by requesting the authenticated and user context types:

通过请求身份验证用户上下文类型来访问组件中的用户状态:

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

导入组件 ( Import Components )

To be able to reference our pages we need to import them. And in order to make importing easy, we'll put them all together in an index.js file so we only have to import it once. So let's create a new file named index.js in our pages directory and export all of our pages from it, as shown below:

为了能够引用我们的页面,我们需要导入它们。 为了使导入变得容易,我们将它们全部放入一个index.js文件中,因此我们只需要导入一次即可。 因此,让我们在pages目录中创建一个名为index.js的新文件,并从中导出所有页面,如下所示:

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

With this, we'll only have to do one import in order to have access to all of our pages.

这样,我们只需要做一次导入就可以访问我们的所有页面。

So let's do that. Open up app.js file and at the top of the file, add the following import statement:

因此,让我们这样做。 打开app.js文件,并在文件顶部添加以下导入语句:

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

运行项目 ( Run The Project )

Now we have an application where our users can sign up, login, and show their user data. So let's try it out!

现在,我们有了一个应用程序,用户可以在其中注册,登录和显示其用户数据。 因此,让我们尝试一下!

As before, start our server by running the following:

和以前一样,通过运行以下命令来启动我们的服务器:

$ node server.js

And if everything is running successfully you should be able to see this message:

如果一切运行顺利,您应该可以看到以下消息:

Listening at http://localhost:3000

So, open up http://localhost:3000 in your browser and try it out!

因此,在浏览器中打开http:// localhost:3000并尝试一下!

结语 ( Wrapping Up )

As you have seen in this tutorial, React is a really powerful tool and when used together with ES6, JSX and Stormpath, building apps suddenly becomes fun again.

正如您在本教程中所看到的, React是一个非常强大的工具,与ES6JSXStormpath结合使用时,构建应用程序突然变得很有趣。

If you have questions regarding the Stormpath React SDK, be sure to check out its API documentation.

如果您对Stormpath React SDK有疑问,请务必查看其API文档

翻译自: https://scotch.io/tutorials/build-a-react-app-with-user-authentication

react 身份证校验校验

 类似资料: