The introduction

The forum system is also a very classic system, many people in college probably wrote, but in three days from open to online deployment is unimaginable, thanks to modern front-end workflow and some excellent open source frameworks, make this possible. The sense of accomplishment that comes with seeing what you have written deployed online is also what motivates many people to keep learning.

Need to use

Front end: React, React – Redux, ANTD, AXIos, Stylus

The backend: egg. Js

Database-related: mysql and Sequelize

Others: Postman, JWT, Nginx, Seven Niuyun…

The directory structure

Client + Service: the front-end view is SRC, and the back-end view is APP

The front end

Style part

I did not use create-React-App scaffolding for the front part, but built it by myself with Webpack. If you are not familiar with Webpack, you are advised to use official scaffolding directly. Since this project only took three days, most of the styles used ANTD, which has a wide variety of components and looks good (strong Amway wave).

Data management

Redux is used for data management, which is currently focused on personal information management after users log in. The Store folder was created to hold actions and Reducers. Create a global store tree, which components need user information just need to connect directly from the store. However, you need to dispatch an action to make changes, which ensures data consistency.

Data request

The request data uses axios. First axios.create() creates an instance, and then interceptors are configured on the instance to intercept the returned result.

  const instance = axios.create({
  xsrfCookieName: 'xsrf-name',
  baseURL: baseDomain
});

instance.interceptors.response.use(function(response) {
  if (response.data.success) {
    return Promise.resolve(response.data)
  } else {
    notification['error']({
      message: response.data.message
    });
    return Promise.reject({
      message: response.data.message
    })
  }
}, function(error) {
  try {
    notification['error']({
      message: error.response.data.message || 'System exception'
    })
    console.log(error.response.status)
    if (error.response.status === 401) {
      setTimeout(() => {
        window.location.href = '/login';
      }, 2000);
    }
  } catch(e) {
    notification['error']({
      message: 'System exception, please try again later! '})}return Promise.reject({
    messageCode: 'sysError'})})Copy the code

Tips: Cross-domain is implemented at development time through devServer forwarding requests.

The back-end

Egg-init egg-example –type=simple Generally, in practical application, Controller will not produce data by itself, nor will it contain complex logic. The complex process should be abstracted into Service, the business logic layer, so our main business logic is still completed in Service, and then return the results to Controller. I won’t go into the details of CRUD, but here are a few key points.

The context of the development

The framework merges the objects defined in app/extend/context.js with the context’s Prototype object and generates CTX objects based on the extended Prototype when processing requests. We can get some data here, for example, we can get the userId resolved from the token here, so we only need to get it once, and then we can use the cache, which improves performance. Or you can wrap some functions here, such as wrapping the native this.staus and this.body together as a returnBody.

  returnBody (status, message, data = {}) {
    this.status = status;
    this.body = {
      data,
      message,
      success: true}}Copy the code

The middleware

You can write custom middleware in the Middleware, such as the authentication middleware I used in this project. Add config.middleware = [‘authorization’] to app/config.default.js; Can be used, is not very convenient?

The database

Database we can use some ORM tools to operate. Sequelize, for example, is an excellent asynchronous ORM framework that allows us to manipulate databases in an OOP manner, gracefully generating secure, maintainable SQL code. It is also very simple to use, but it is worth noting that it is best to configure the auto-generated files in the database directory before initialization, so that it is easy to manage.

Sequelize Development environment configuration

  "development": {
  "username": "root", / / mysql accounts"password": "yourpassword", / / mysql password"database": "newbeeForum"// Database name"port": 3306,
  "host": "127.0.0.1"."dialect": "mysql"
}
Copy the code

Posting

Post pictures are first uploaded to seven niuyun, and then return to the link, the database only saved the link. For specific operations, please refer to the developer documentation of Qiuniuyun.

The JavaScript SDK: developer.qiniu.com/kodo/sdk/12… Node. Js SDK: developer.qiniu.com/kodo/sdk/12…

jwt

For login, JWT is used for cross-domain authentication. After successful login, a token will be issued and planted into the cookie. Authentication middleware uses this token to identify whether the user has permission to access the page.

Issued token: const token = JWT. Sign ({userId: existUser userId}, enclosing app. Config. JwtSecret, {expiresIn: ‘7 d});

password

It is immoral to save the user password in plain text, so I use crypto to encrypt and save the user password. When logging in, I also encrypt the plaintext password first and compare it with the database. Only when the plaintext password is the same, can I log in.

Encrypt and save user password: user.password = crypto.createHmac(‘sha256’, this.app.config.password_secret) .update(user.password) .digest(‘hex’);

The deployment of online

Deployment conditions: Install Node 8.0 or later, mysql, and Nginx on the server

Mine is the server of Tencent cloud, the system is Centos7. NPM install –production; tar -zcvf; tar -zcvf; tar -zcvf; tar -zcvf /release. TGZ, put it on the server, unzip it, and NPM start is ready to run. Finally, configure Nginx forward request to achieve cross-domain.

Forwarding request:

` ` ` / / if only host, port, convert the location/project {proxy_pass http://127.0.0.1:8080/project; } / / if the path is also changed, you need to set the cookie path conversion, or cookie will lost the location/proxy_path {proxy_pass http://127.0.0.1:8080/project; } ` ` `Copy the code

Tips: If the React front end is completely blank, there may be a path problem. Pay attention to relative paths or absolute paths.

The last

  • Source point I
  • Since I only wrote for three days, I only realized the basic functions of login, registration and Posting, which can be gradually improved later
  • Deployed on the web site, I can experience the newbeeforum. Newbeelity. Cn (registered captcha disorderly filling line)
  • Code word is not easy, welcome star
  • You got any big shots? Senior year
  • over