JWT based user Authentication using ReactJs, Node Express, and MySQL

Geethika Sandamali
8 min readOct 25, 2021

--

Part 1: User registration and login without JWT

This series of articles demonstrates a JWT based user authentication system using ReactJS, Node Express, and MySQL. This series contains three main articles. During the first article, we will explain how to build a user registration and login page without JWT. During the second article, we will explain how to add Cookies, Sessions, and hashing to the user registration and login page, and in the third article, we will explain integrating JWT into the existing system.

In this first article, the following topics will be covered.

  1. Develop user registration
  2. Develop user login

Then, let’s look at each topic.

1. Develop user registration

1.1. Build ReactJs registration page

First, we need to create a folder called “client” inside our project folder which will be used for the client applications. Then, we need to install the reactJs inside our client folder. To install the reactJs, open the terminal and navigate to the client folder and enter the following command on the terminal.

npx create-react-app .

Note: your folder name should be in lowercase letters “client” and there should be a dot at the end of the terminal command.

After creating the React application, navigate to the src folder which is inside the client folder. Then we need to remove the unnecessary files except for the App.css, App.js, and index.js. Mentioned files are shown below.

Note: both registration and login views of our page were developed at this moment.

client/src/App.js

import React from “react”;
import ‘./App.css’;

function App() {

return (
<div className=”App”>
<div className=”registration”>
<h1>Registration</h1>
<label>Username</label>
<input type=”text” /><br/>
<label>password</label>
<input type=”text” /> <br />
<button> Register</button>
</div>
<div className=”login”>
<h1>Login</h1>
<input type=”text” placeholder=”Username…” /> <br/>
<input type=”password” placeholder=”Password…” />
<button >Login</button>
</div>
</div>
);
}

export default App;

client/src/ index.js

import React from ‘react’;
import ReactDOM from ‘react-dom’;
import ‘./App.css’;
import App from ‘./App’;

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById(‘root’)
);

client/src/ App.css

.App {
text-align: center;
}

.registration {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.login {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
input {
width: 250px;
height: 40px;
}

1.2. Build a Node Express server, then add the “/register” route

First, we need to create a folder called “server” inside our project folder which will be used for the server application. Then, we need to install the express and NodeJs inside the server folder, for that we need to use the npm init command to create a package.json file inside the server folder.

npm init

The package.json file will be displayed as below.

{
“name”: “server”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1"
},
“author”: “”,
“license”: “ISC”,
“dependencies”: {
“express”: “⁴.17.1”
}
}

Now install Express in the server application and save it in the dependencies list using the following command on the terminal.

npm install express -–save

Then we need to add the index.js file inside the server folder. This index.js file will be used to develop our Express server. The skeleton of the server application is shown below.

server/ index.js

const express = require(“express”);
const app = express();
app.use(express.json());app.listen(3001, () => {
console.log(“running server”);
});

1.3. MySQL setup and query

First, we need to install the latest MySQL server on your computer and online resources can be used for this task. After that, we need to open MySQL Workbench to create a schema and a table. MySQL Workbench's main interface is shown below.

First, inside the workbench main interface click “File” on the upper left menu bar to get the dropdown menu. Then, inside the dropdown menu, click “New Model”. After clicking you will get the following interface.

Then inside the current interface, click the “+” button on the upper right side of the “Physical Schemas” toolbar to add a new schema and you can change the name of this schema as you want. During this project, we named the schema “loginsystem”.

Then inside the “Physical Schemas” toolbar, double click on “Add Table”. This automatically loads the table and you can name the table. During this project, we named the table “users”. Then, you can add the two columns username and password and change the settings of the two columns as follows.

Note: Data type of the password column is set to VARCHAR(500). This will ease during the second part the hashing of passwords.

Finally, we need to install the “mysql2” Javascript module on our server dependencies. However, “mysql” module was used during the tutorial I followed, but newer versions of MySQL database servers don’t support the “mysql” Javascript module. Therefore, “mysql2” should be used with the newer versions of MySQL database servers. To install the “mysql2” Javascript module, we can use the following command.

npm install --save mysql2

Finally, we need to create a connection to the database from the server application using the following code. Furthermore, you need to replace ‘user’ and ‘add-password’ with the correct values. And then specify the database name (loginsystem) in the createConnection command. Following changes should be done to server/index.js.

first, import mysql2 module

const mysql = require(“mysql2”);

second, create a db connection

const db = mysql.createConnection({
user: “root”,
host: “localhost”,
password: “add-password”,
database: “loginsystem”,
});

In the client application, we need to get username and password from the registration view. For that, we need to use react state hook (useState). “useState” is a Hook that lets you add React state to function components. Following changes should do to the client/src/App.js.

first, declare two state variables inside “function App()”

const [usernameReg, setUernameReg] = useState(“”);
const [passwordReg, setPasswordReg] = useState (“”);

second, define functions to get the text value from the input field while the user types, the onChange handler updates the state with the input’s value accessed from the event object: event.target.value as follows.

return (
<div className=”App”>
<div className=”registration”>
..........
<input
type=”text”
onChange={(e) => {
setUernameReg(e.target.value);
}}

/><br/>
..........
<input
type=”text”
onChange={(e) =>{
setPasswordReg(e.target.value);
}}

/> <br />
..........
</div>

..........
</div>
);
}

Then we need to create a route in the server application to insert new users into the database. Following changes are done to the server/ index.js.

app.post(‘/register’, (req, res)=> {
db.execute(
“INSERT INTO users (username, password) VALUES (?,?)”,
[username, password],
(err, result)=> {
console.log(err);
}
);
});

1.4. HTTP request using Axios in React

Then we need to install the Axios to our client application which helps us make HTTP requests to HTTP servers. To install the Axios module, we can use the following command.

npm i --save axios

Then we can send the username and password to the server application when the user clicks the “register” button. Following changes are done to the client/src/App.js.

First, we need to import Axios as follows.

import Axios from ‘axios’;

Second, we need to use the onclick attribute to connect the click events to the function register. This will make use of the Axios module to initiate the POST requests.

function App() {

..........

const register = () => {
Axios.post(“
http://localhost:3001/register", {
username: usernameReg,
password: passwordReg,
}).then((response) => {
console.log(response);
});
};


return (
<div className=”App”>
<div className=”registration”>
..........
<button onClick={register} > Register</button>
</div>
..........
</div>
);
}

After changing the client application, we need to get the password and username from the server application. Following changes are done to the server/ index.js.

app.post(‘/register’, (req, res)=> {

const username = req.body.username;
const password = req.body.password;


..........
});

1.5. Setting up CORS with Express

We need to install the cors to our server application. CORS is an acronym for Cross-Origin Resource Sharing. It is a mechanism to allow or restrict requested resources on a web server depending on where the HTTP request originated. In other words, CORS is a browser security feature that restricts cross-origin HTTP requests with other servers and specifies which domains can access your resources. CORS javascript module can be installed using the below command.

npm i — save cors

To add CORS to our server application, the following changes are done to the server/ index.js.

First, we need to import CORS

const cors = require(“cors”);

second, we need to enable CORS in our server application for connection between server and client applications.

app.use(
cors({
origin: [“http://localhost:3000"],
methods: [“GET”, “POST”],
credentials: true,
})
);

2. Develop user login

Then we need to develop the login feature that user can use to login into the system by providing a username and a password. At the moment this feature will only display the name of the logged user. But in real applications, we can use this login feature to authorize users by authenticating them using their username and password. So, let’s create the login feature to display the username once the “Login” button is pressed.

2.1. Add ‘/login’ route

To add this login feature, first, we need to add another Express route called “/login” to the server application. Inside the route, we need to get the user date from the database and authenticate the user. Following changes were done to the server/ index.js when adding the route.

app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;

db.execute(
"SELECT * FROM users WHERE username = ? AND password = ?",
[username, password],
(err, result)=> {
if (err) {
res.send({err: err});
}

if (result.length > 0) {
res.send( result);
}else({message: "Wrong username/password comination!"});
}
}
);
});

2.2. HTTP using Axios

Finally, we need to get the username and password from the client application using state. Then we need to send HTTP requests to the “/login” endpoint using Axios. Following changes were done to the client/src/App.js as we did for the register feature.

function App() {

..........

const [username, setUername] = useState(“”);
const [password, setPassword] = useState (“”);

const [loginStatus, setLoginStatus] = useState("");

..........

const login = () => {
Axios.post(“
http://localhost:3001/login”, {
username: username,
password: password,
}).then((response) => {
if (!response.data.message) {
setLoginStatus( response.data.message);
} else {
setLoginStatus (response.data[0].message);
}
});
};


return (
<div className=”App”>
..........

<div className=”login”>
<h1>Login</h1>
<input
type=”text”
placeholder=”Username…”
onChange = { (e) => {
setUername (e.target.value);
}}

/> <br/>
<input
type=”password”
placeholder=”Password…”
onChange = { (e) => {
setPassword (e.target.value);
}}

/>
<button onClick={login}>Login</button>
</div>
<h1> {loginStatus}</h1>
</div>
);
}

Tutorial followed by the “PedroTech” YouTube channel.
Here is the link: https://www.youtube.com/watch?v=W-sZo6Gtx_E

You can access the full code here and the second part of this article series here.

--

--

Geethika Sandamali

Welcome to my blog! Programming and coding are my passions, and I’m dedicated to constantly enhancing my skills and knowledge. https://github.com/gsandamali