0% found this document useful (0 votes)
4 views15 pages

Frontend-User Authentication and Authorization (React App)

Uploaded by

trzong-ming.teoh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views15 pages

Frontend-User Authentication and Authorization (React App)

Uploaded by

trzong-ming.teoh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

User Authentication and Authorization - Frontend (React app)

Task 1: Setup a new react app


1. Create a new project directory. For example, name it as “USER-AUTHENTICATION”

mkdir USER-AUTHENTICATION

2. Inside the new project directory, in the terminal, create a new react app, you can name
the app as ‘frontend’ or ‘client’
npx create-react-app frontend

3. To start the new react app:


cd frontend
npm start

4. Go to ‘src’ directory, you will need to remove some boilerplate in your React application.
a. Open ‘index.js’ file to remove the following codes:
i. import reportWebVitals from './reportWebVitals';
ii. reportWebVitals();

b. Open ‘App.js’ file to:


i. Remove the boilerplate codes (highlighted in GREEN color).
import logo from './logo.svg';
import './App.css';

function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}

ii. Add this line of code: <h1>Hello</h1>

function App() {
return (
<div className="App">
<h1>Hello</h1>
</div>
);
}
c. Open ‘index.css’ and remove all the CSS styles and replace them with the
following CSS styles:

*,
::before,
::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}

d. Remove the following files from ‘src’ directory:


i. App.css
ii. App.test.js
iii. logo.svg
iv. reportWebVitals.js
v. setupTests.js

5. Restart your React application by running npm start in your terminal.

Task 2: Implement frontend


1. Install the following in your terminal:

npm install react-cookie react-router-dom react-toastify axios

React dependencies Description


react-cookie A lightweight React cookie library for reading and
writing cookies.
react-router-dom React bindings for handling routing in your React
application.
react-toastify A popular library for displaying notifications (toasts) in
React applications.
axios A library for making HTTP requests. Useful for
interacting with APIs.

2. Update the index.js file in the frontend directory with the code snippet below to:
a. Wrapping your App component with BrowserRouter is necessary to enable
client-side routing and take advantage of its benefits in your application.
b. Import react-toastify so it can be available in your application.
c. Note: Remove the React.StrictMode later when you are testing the application
and your data is being fetched twice.

import React from 'react';


import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import {BrowserRouter} from 'react-router-dom';
import 'react-toastify/dist/ReactToastify.css';

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);

3. Create the pages directory in your frontend’s src directory, which will contain the
Home.jsx file, Login.jsx file, Signup.jsx and index.js to export the components.

4. Fill the Login.jsx in the pages directory, with the code below.
import React from "react";

const Login = () => {


return <h1>Login Page</h1>;
};

export default Login

5. Fill the Signup.jsx in the pages directory, with the code below.
import React from "react";

const Signup = () => {


return <h1>Signup Page</h1>;
};

export default Signup

6. Fill the Home.jsx in the pages directory, with the code below.
import React from "react";

const Home = () => {


return <h1>Home Page</h1>;
};

export default Home

7. Go into the index.js file in the pages directory to export the newly created components.
This method makes importing components easier by requiring only one import line.

export {default as Login} from './Login'


export {default as Signup} from './Signup'
export {default as Home} from './Home'

8. Now, update the App.js file in the src directory with the code below.
import { Route, Routes } from "react-router-dom";

import { Login, Signup } from "./pages";


import Home from "./pages/Home";

function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</div>
);
}

export default App;

9. Test the routes in your application:


a. http://localhost:3000
b. http://localhost:3000/login
c. http://localhost:3000/signup

Task 3: Handle the Signup Logic


Add the following code snippet to the Signup.jsx file in the pages directory:

import React, { useState } from "react";


import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";

const Signup = () => {


const navigate = useNavigate();
const [inputValue, setInputValue] = useState({
email: "",
password: "",
username: "",
});
const { email, password, username } = inputValue;
const handleOnChange = (e) => {
const { name, value } = e.target;
setInputValue({
...inputValue,
[name]: value,
});
};
const handleError = (err) =>
toast.error(err, {
position: "bottom-left",
});
const handleSuccess = (msg) =>
toast.success(msg, {
position: "bottom-right",
});

const handleSubmit = async (e) => {


e.preventDefault();
try {
const { data } = await axios.post(
"http://localhost:4000/signup",
{
...inputValue,
},
{ withCredentials: true }
);
const { success, message } = data;
if (success) {
handleSuccess(message);
setTimeout(() => {
navigate("/");
}, 1000);
} else {
handleError(message);
}
} catch (error) {
console.log(error);
}
setInputValue({
...inputValue,
email: "",
password: "",
username: "",
});
};

return (
<div className="form_container">
<h2>Signup Account</h2>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
name="email"
value={email}
placeholder="Enter your email"
onChange={handleOnChange}
/>
</div>
<div>
<label htmlFor="email">Username</label>
<input
type="text"
name="username"
value={username}
placeholder="Enter your username"
onChange={handleOnChange}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
name="password"
value={password}
placeholder="Enter your password"
onChange={handleOnChange}
/>
</div>
<button type="submit">Submit</button>
<span>
Already have an account? <Link to={"/login"}>Login</Link>
</span>
</form>
<ToastContainer />
</div>
);
};

export default Signup;

Task 4: Handle the Login Logic


Add the following code snippet to the Login.jsx file in the pages directory:

import React, { useState } from "react";


import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";

const Login = () => {


const navigate = useNavigate();
const [inputValue, setInputValue] = useState({
email: "",
password: "",
});
const { email, password } = inputValue;
const handleOnChange = (e) => {
const { name, value } = e.target;
setInputValue({
...inputValue,
[name]: value,
});
};

const handleError = (err) =>


toast.error(err, {
position: "bottom-left",
});
const handleSuccess = (msg) =>
toast.success(msg, {
position: "bottom-left",
});

const handleSubmit = async (e) => {


e.preventDefault();
try {
const { data } = await axios.post(
"http://localhost:4000/login",
{
...inputValue,
},
{ withCredentials: true }
);
console.log(data);
const { success, message } = data;
if (success) {
handleSuccess(message);
setTimeout(() => {
navigate("/");
}, 1000);
} else {
handleError(message);
}
} catch (error) {
console.log(error);
}
setInputValue({
...inputValue,
email: "",
password: "",
});
};

return (
<div className="form_container">
<h2>Login Account</h2>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
name="email"
value={email}
placeholder="Enter your email"
onChange={handleOnChange}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
name="password"
value={password}
placeholder="Enter your password"
onChange={handleOnChange}
/>
</div>
<button type="submit">Submit</button>
<span>
Already have an account? <Link to={"/signup"}>Signup</Link>
</span>
</form>
<ToastContainer />
</div>
);
};

export default Login;

Task 5: Handle the Home Page Logic


Add the following code snippet to the Home.jsx file in the pages directory:
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useCookies } from "react-cookie";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";

const Home = () => {


const navigate = useNavigate();
const [cookies, removeCookie] = useCookies([]);
const [username, setUsername] = useState("");
useEffect(() => {
const verifyCookie = async () => {
if (!cookies.token) {
navigate("/login");
}
const { data } = await axios.post(
"http://localhost:4000",
{},
{ withCredentials: true }
);
const { status, user } = data;
setUsername(user);
return status
? toast(`Hello ${user}`, {
position: "top-right",
})
: (removeCookie("token"), navigate("/login"));
};
verifyCookie();
}, [cookies, navigate, removeCookie]);
const Logout = () => {
removeCookie("token");
navigate("/signup");
};
return (
<>
<div className="home_page">
<h4>
{" "}
Welcome <span>{username}</span>
</h4>
<button onClick={Logout}>LOGOUT</button>
</div>
<ToastContainer />
</>
);
};

export default Home;

Task 6: Add CSS styles


Add the CSS styles below into your index.css file:
*,
::before,
::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}

label {
font-size: 1.2rem;
color: #656262;
}

html,
body {
height: 100%;
width: 100%;
}

body {
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(
90deg,
rgba(2, 0, 36, 1) 0%,
rgba(143, 187, 204, 1) 35%,
rgba(0, 212, 255, 1) 100%
);
font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.form_container {
background-color: #fff;
padding: 2rem 3rem;
border-radius: 0.5rem;
width: 100%;
max-width: 400px;
box-shadow: 8px 8px 24px 0px rgba(66, 68, 90, 1);
}

.form_container > h2 {
margin-block: 1rem;
padding-block: 0.6rem;
color: rgba(0, 212, 255, 1);
}

.form_container > form {


display: flex;
flex-direction: column;
gap: 1.4rem;
}

.form_container div {
display: flex;
flex-direction: column;
gap: 0.3rem;
}

.form_container input {
border: none;
padding: 0.5rem;
border-bottom: 1px solid gray;
font-size: 1.1rem;
outline: none;
}

.form_container input::placeholder {
font-size: 0.9rem;
font-style: italic;
}

.form_container button {
background-color: rgba(0, 212, 255, 1);
color: #fff;
border: none;
padding: 0.6rem;
font-size: 1rem;
cursor: pointer;
border-radius: 0.3rem;
}

span a {
text-decoration: none;
color: rgba(0, 212, 255, 1);
}

.home_page {
height: 100vh;
width: 100vw;
background: #000;
color: white;
display: flex;
justify-content: center;
align-items: center;
text-transform: uppercase;
font-size: 3rem;
flex-direction: column;
gap: 1rem;
}

.home_page span {
color: rgba(0, 212, 255, 1);
}

.home_page button {
background-color: rgb(27, 73, 83);
color: #fff;
cursor: pointer;
padding: 1rem 3rem;
font-size: 2rem;
border-radius: 2rem;
transition: ease-in 0.3s;
border: none;
}

.home_page button:hover {
background-color: rgba(0, 212, 255, 1);
}

@media only screen and (max-width: 1200px){


.home_page{
font-size: 1.5rem;
}
.home_page button {
padding: 0.6rem 1rem;
font-size: 1.5rem;
}
}
Task 7: Test the frontend and backend
1. After implementing the Frontend and backend, you may test the user authentication
and verification by starting your backend ExpressJS and frontend React applications.
a. Run npm start in your terminal.
b. NOTE: To run the Frontend and Backend in one command only, you may
refer to the following reference (Use either “concurrently” library or “npm-run-
all”)
Reference: https://medium.com/@rwijayabandu/how-to-run-frontend-and-
backend-with-one-command-55d5f2ce952c

2. Test the Signup, Login and Home routes in your application to view the login, signup
and home pages
• http://localhost:3000/signup
• http://localhost:3000/login
• http://localhost:3000

Figure 1: Signup page

Figure 2: Home page


Figure 3: Login page

You might also like