Question

In: Computer Science

Create a Registration and login page using React,nodejs and all the data should store in MongoDB...

Create a Registration and login page using React,nodejs and all the data should store in MongoDB database.

Solutions

Expert Solution

Register

Let’s Start From the Frontend

We need to get the sample code from AdminLTE. Copy the code wrapped inside <div class="login-box"></div> tags and paste it in a new file named register.js. Convert the pasted HTML code to JSX using the previously installed VSCode extension.

Then, we add Formik and Yup dependencies to easily integrate form and form validation.

1

yarn add formik yup

Import these two packages inside register.js.

1

2

3

import React, { Component } from "react";

import { Formik } from "formik";

import * as Yup from "yup";

Wrap the created form using the special tag <Formik>. You have to add initial values for the fields that are being used. We use the onSubmit function to display the form values on the console when a user submits the form.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

render() {

    return (

      <div className="register-box">

        <div className="register-logo">

          <a href="../../index2.html">

            <b>Basic</b>POS

          </a>

        </div>

        <div className="card">

          <div className="card-body register-card-body">

            <p className="login-box-msg">Register a new membership</p>

            <Formik

              initialValues={{

                fullname: "",

                email: "",

                password: "",

                confirm_password: ""

              }}

              onSubmit={(values) => {

                console.log(values);

              }}

            >

              {props => this.showForm(props)}

            </Formik>

          </div>

          {/* /.form-box */}

        </div>

        {/* /.card */}

      </div>

    );

  }

}

Now we add the showForm function to clean the code and save time.

1

2

3

4

5

6

7

8

9

showForm = ({

    values,

    errors,

    touched,

    handleChange,

    handleSubmit,

    setFieldValue,

    isSubmitting

  }) => {}

We inject parameters that are passed on to the form inside this function.

We use onSubmit={handleSubmit} to capture form submission, onChange={handleChange} to capture the values inserted to the forms, and disabled={isSubmitting} to disable form submission.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

return (

      <form onSubmit={handleSubmit}>

        <div className="form-group has-feedback">

          <input

            type="text"

            name="username"

            onChange={handleChange}

            value={values.username}

            className="form-control"

            placeholder="Username"

        

          />

        </div>

        <div className="form-group has-feedback">

          <input

            type="text"

            name="email"

            onChange={handleChange}

            value={values.email}

            placeholder="Email"

          />

        </div>

        <div className="form-group has-feedback">

          <input

            type="password"

            name="password"

            onChange={handleChange}

            value={values.password}

            className="form-control"

            placeholder="Password"

          />

        </div>

        <div className="form-group has-feedback">

          <input

            type="password"

            name="confirm_password"

            onChange={handleChange}

            placeholder="Confirm Password"

          />

        </div>

        <div className="row">

          <div className="col-md-12">

            <button

              disabled={isSubmitting}

              type="submit"

              className="btn btn-primary btn-block btn-flat"

            >

              Confirm

            </button>

          </div>

        </div>

      </form>

    );

You can now see the resulting register form.

POS Register page

Try to submit the form and see what happens. Read the output of the console.

2. Formik form object data

Though we have finished creating the form, we need to add client-side validation to the form before sending data to the server.

Validation with Yup

We can create a validation schema as expected using Yup.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

const SignupSchema = Yup.object().shape({

  username: Yup.string()

    .min(2, "username is Too Short!")

    .max(50, "username is Too Long!")

    .required("username is Required"),

  email: Yup.string()

    .email("Invalid email")

    .required("Email is Required"),

  password: Yup.string().required("Password is required"),

  confirm_password: Yup.string().oneOf(

    [Yup.ref("password"), null],

    "Both password need to be the same"

  )

});

Then add the validation schema to Formik.

1

2

3

4

5

6

7

8

9

10

11

12

13

           <Formik

              initialValues={{

                fullname: "",

                email: "",

                password: "",

                confirm_password: ""

              }}

              onSubmit={(values, { setSubmitting }) => {

                console.log(values);

                setSubmitting(false);

              }}

           validationSchema={SignupSchema}

           >

Now we add CSS that is used to display an error message and change the input border color.

Add the CSS class is-invalid to change the border color to red.

1

2

3

4

5

           className={

              errors.username && touched.username

                ? "form-control is-invalid"

                : "form-control"

            }

Display the error message from the validation schema.

1

2

3

4

5

         {errors.fullname && touched.fullname ? (

            <small id="passwordHelp" class="text-danger">

              {errors.username}

            </small>

          ) : null}

You can see the full form code below.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

return (

      <form onSubmit={handleSubmit}>

        <div className="form-group has-feedback">

          <input

            type="text"

            name="username"

            onChange={handleChange}

            value={values.username}

            className="form-control"

            placeholder="Username"

            className={

              errors.username && touched.username

                ? "form-control is-invalid"

                : "form-control"

            }

          />

          {errors.fullname && touched.fullname ? (

            <small id="passwordHelp" class="text-danger">

              {errors.username}

            </small>

          ) : null}

        </div>

        <div className="form-group has-feedback">

          <input

            type="text"

            name="email"

            onChange={handleChange}

            value={values.email}

            className={

              errors.email && touched.email

                ? "form-control is-invalid"

                : "form-control"

            }

            placeholder="Email"

          />

          {errors.email && touched.email ? (

            <small id="passwordHelp" class="text-danger">

              {errors.email}

            </small>

          ) : null}

        </div>

        <div className="form-group has-feedback">

          <input

            type="password"

            name="password"

            onChange={handleChange}

            value={values.password}

            className="form-control"

            placeholder="Password"

            className={

              errors.password && touched.password

                ? "form-control is-invalid"

                : "form-control"

            }

          />

          {errors.password && touched.password ? (

            <small id="passwordHelp" class="text-danger">

              {errors.password}

            </small>

          ) : null}

        </div>

        <div className="form-group has-feedback">

          <input

            type="password"

            name="confirm_password"

            onChange={handleChange}

            className={

              errors.confirm_password && touched.confirm_password

                ? "form-control is-invalid"

                : "form-control"

            }

            placeholder="Confirm Password"

          />

          {errors.confirm_password && touched.confirm_password ? (

            <small id="passwordHelp" class="text-danger">

              {errors.confirm_password}

            </small>

          ) : null}

        </div>

        <div className="row">

          <div className="col-md-12">

            <button

              disabled={isSubmitting}

              type="submit"

              className="btn btn-primary btn-block btn-flat"

            >

              Confirm

            </button>

          </div>

          {/* /.col */}

        </div>

      </form>

    );

The registration form now looks like this.

3.Formik Validation error

Now we can send an HTTP request with Axios to submit the form.

First, install and import Axios.

1

yarn add axios

Import axios to register.js.

1

import axios from "axios";

Create a function to send a post request to the backend.

1

2

3

4

5

6

7

8

9

10

submitForm = (values) => {

    axios

      .post("http://localhost:8080/register", values)

      .then(res => {

        console.log(res);

      })

      .catch(error => {

        console.log(error);

      });

  };

Add this function to the onSubmit function inside Formik and pass the form values and the history object to navigate to another page.

1

2

3

4

5

6

7

8

9

10

11

12

13

           <Formik

              initialValues={{

                fullname: "",

                email: "",

                password: "",

                confirm_password: ""

              }}

              onSubmit={(values, { setSubmitting }) => {

                this.submitForm(values, this.props.history);

                setSubmitting(false);

              }}

              validationSchema={SignupSchema}

            >

We have completed the frontend implementation of authentication. Next. we will configure the backend to receive the submitted registration form.

Backend: Create a User on the Database

Create a new folder named models and create a file named user_schema.js inside the folder.

1

2

3

4

5

6

7

8

9

const mongoose = require("mongoose");

const schema = mongoose.Schema({

  username: String,

  email: String,

  password: String,

  level: { type: String, default: "normal" },

  created: { type: Date, default: Date.now }

});schema.index({ username: 1 }, { unique: true });

module.exports = mongoose.model("users", schema);

Now we have a table structure to store user data.

Next import user_schema to index.js.

1

2

require("./db");

const Users = require("./models/user_schema");

We can use the create function to create a new user.

1

2

3

4

5

6

7

8

9

app.post("/register", async (req, res) => {

  try {

    req.body.password = await bcrypt.hash(req.body.password, 8);

    await Users.create(req.body);

    res.json({ result: "success", message: "Register successfully" });

  } catch (err) {

    res.json({ result: "error", message: err.errmsg });

  }

});

Let’s go back to the frontend to handle the response sent by the server.

Add SweetAlert

To handle the response message, we use SweetAlert. First, install the package using the command yarn add sweetalert. Import the package to register.js as the following line of code shows.

import swal from "sweetalert";

Now use SweetAlert to handle the success or error response accordingly.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

submitForm = (values, history) => {

    axios

      .post("http://localhost:8080/register", values)

      .then(res => {

        console.log(res.data.result);

        if (res.data.result === "success") {

          swal("Success!", res.data.message, "success")

          .then(value => {

            history.push("/login");

          });

        } else if (res.data.result === "error") {

          swal("Error!", res.data.message, "error");

        }

      })

      .catch(error => {

        console.log(error);

        swal("Error!", "Unexpected error", "error");

      });

  };

Now add submitForm to onSubmit.

1

2

3

4

             onSubmit={(values, { setSubmitting }) => {

                this.submitForm(values, this.props.history);

                setSubmitting(false);

              }}

Submit valid data through the form and see how the form works.

success submission result

Submit an invalid set of data through the form to see how the form handles errors.

error submission result

Now you can view the registered user data.

result data in mongodb

LOG IN

Backend: Authentication with JWT

We use JWT to handle login by generating a JSON Web Token which can be sent back to the browser to be stored in the LocalStorage.

Create a file named jwt.js inside the backend folder.

Import fs and path libraries to read private and public keys.

1

2

3

4

5

const fs = require('fs');

const path = require('path');

const jwt = require('jsonwebtoken');

var publicKEY = fs.readFileSync(path.join(__dirname + 'https://soshace-12d3e.kxcdn.com/public.key'), 'utf8');

var privateKEY = fs.readFileSync(path.join(__dirname + 'https://soshace-12d3e.kxcdn.com/private.key'), 'utf8');

Then, define the issuer as follows.

1

2

3

var i = 'Krissio';     // Issuer (Software organization who issues the token)

var s = '[email protected]'; // Subject (intended user of the token)

var a = 'https://kriss.io'; // Audience (Domain within which this token will live and function)

Create a function named sign to create JWTs.

1

2

3

4

5

6

7

8

9

10

11

12

13

module.exports = {

    sign : (payload)=>{

         // Token signing options

         var signOptions = {

            issuer: i,

            subject: s,

            audience: a,

            expiresIn: "30d",    // 30 days validity

            algorithm: "RS256"

        };

        return jwt.sign(payload, privateKEY, signOptions);

    },

}

Now import the file to index.js.

1

const jwt = require("./jwt");

We can now implement the login-from database. We search the user from the database and compare the stored and sent passwords using bcrypt.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

app.post("/login", async (req, res) => {

  let doc = await Users.findOne({ username: req.body.username });

  if (doc) {

    if (bcrypt.compareSync(req.body.password, doc.password)) {

      const payload = {

        id: doc._id,

        level: doc.level,

        username: doc.username

      };

      let token = jwt.sign(payload);

      console.log(token);

      res.json({ result: "success", token, message: "Login successfully" });

    } else {

      // Invalid password

      res.json({ result: "error", message: "Invalid password" });

    }

  } else {

    // Invalid username

    res.json({ result: "error", message: "Invalid username" });

  }

});

Login Frontend

We can copy the code from register.js and paste it to login.js. Update the form by removing the username and confirm_password input fields. You can view all updates here.

We need to change how the response is handled in the frontend by adding the code to store the JWT token in LocalStorage. Then, redirect to the dashboard screen.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

submitForm = (values, history) => {

    axios

      .post("http://localhost:8080/login", values)

      .then(res => {

        if (res.data.result === "success") {

          localStorage.setItem("TOKEN_KEY", res.data.token);

          swal("Success!", res.data.message, "success")

         .then(value  => {

            history.push("/dashboard");

          });

        } else if (res.data.result === "error") {

          swal("Error!", res.data.message, "error");

        }

      })

      .catch(error => {

        console.log(error);

        swal("Error!", error, "error");

      });

  };

The resulting login page looks like this.

Success result


Related Solutions

using PDO, MYSQL, and Html, how can i create a simple registration and login form for...
using PDO, MYSQL, and Html, how can i create a simple registration and login form for cPanel?
Using the zip file provided, create a secure login/registration app. Make sure that your game pages...
Using the zip file provided, create a secure login/registration app. Make sure that your game pages (at least two) are unavailable to unregistered users. Upload a zip file with your working PHP application. Contents of zip Index.php ----------------- <!DOCTYPE html> <html>     <head>         <meta charset="UTF-8">         <title></title>     </head>     <body>         <?php         // 1. display error message in the session (if any): $_SESSION['error']         // 2. display either the user's name and the game menu or the...
create a todo app using React and MongoDB. User can also delete the tasks, add tasks,...
create a todo app using React and MongoDB. User can also delete the tasks, add tasks, update tasks and edit tasks using edit, del, update and add button.
Create following webpage in HTML : 1. Login Page This is the first page the user...
Create following webpage in HTML : 1. Login Page This is the first page the user should see. The user can login, signup, or continue as a guest. Your task is to implement the following features: a) Signup form This form should collect the information required for creating a new account on your movie database website. At the least, it should collect an email address, username, avatar image/graphic, first name, last name, and a password. You can ask for more...
1 -​Create the code to generate a default web page. The contents of this page should...
1 -​Create the code to generate a default web page. The contents of this page should be Your​​Name, right justified
Create a typedef fruitType using the struct fruitType_struct to store the following data about a fruit:...
Create a typedef fruitType using the struct fruitType_struct to store the following data about a fruit: name (string, up to 50 characters long) color (string, up to 10 characters long) fat (integer) sugar (integer) carbohydrate (integer) Write a void function called printFruit that takes a fruitType parameter and prints the data (as shown in the example below). Declare a variable of type fruitType to store the following data: name: banana color: yellow fat: 1 sugar: 15 carbohydrate: 22 then use...
Create a description of a university course registration system. You should include features for students, faculty,...
Create a description of a university course registration system. You should include features for students, faculty, and administrators. For example, students need to use the system to add and drop courses that they attend, faculty needs to add and drop courses that they offer and the Registrar needs to allocate and de-allocate resources for courses that are added or dropped. Each type of user also has to satisfy some constraints, such as how many courses they take (students), teach (faculty)...
HTML Create a page of texts that uses inline elements. The page should contain a citation,...
HTML Create a page of texts that uses inline elements. The page should contain a citation, a term definition, a subscript, a superscript and some highlighted texts.
Create a web page that contains a simple math test. The page should have the following...
Create a web page that contains a simple math test. The page should have the following arithmetic problems. Add a button under each problem which, when clicked, will display a prompt for the user to enter the answer. Add a swcond button which, when clicked, will check to see if the user's answer is correct. The output should be either "correct" or "incorrect" displayed in an alert box. 1. 5+9= 2. 4*6= 3. 25-14= 4. 48/3= 5. 26%6=
Create a Web page about yourself containing the following: Notepad++ The page should have a light...
Create a Web page about yourself containing the following: Notepad++ The page should have a light green background and a one inch margin. The Web page should contain: At least three headings, h1 to h3. At least two paragraphs about you. A numbered list with at least three hyperlinks. The hyperlinks cannot be the ones we created in class today which were the links to Yahoo and Google. Two horizontal rules. All the h1, h2, and h3 tags should have...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT