/plushcap/analysis/strapi/strapi-how-to-build-a-real-time-chat-forum-using-strapi-socket-io-react-and-mongo-db

Real-time Chat Application Using Strapi, Next, Socket.io, and PostgreSQL

What's this blog post about?

In this tutorial, we will be building a chat application with role-based authentication using React and Strapi version 4. We will cover the following topics: 1. Setting up the project 2. Creating a user registration form 3. Implementing email verification 4. Building the login system 5. Role-based authentication 6. Creating a chat room with socket.io 7. Implementing role-based access control (RBAC) 8. Testing and deployment By the end of this tutorial, you will have built a fully functional chat application with user registration, email verification, login system, role-based authentication, and real-time messaging capabilities. To follow along with this tutorial, you should have basic knowledge of React, Node.js, Express, and MongoDB. You can also refer to the GitHub repository for the complete code: https://github.com/AustinOsuji/chat-app-strapi-react Let's get started! 1. Setting up the project First, create a new React app using Create React App: ```bash npx create-react-app chat-app cd chat-app ``` Next, install the following dependencies: ```bash npm install axios antd socket.io-client styled-components ``` 2. Creating a user registration form Create a new file `UserForm.js` in the `src` directory and add the following code: ```javascript import React, { useState } from "react"; import { Input, Button, Form } from "antd"; import { UserOutlined, LockOutlined } from "@ant-design/icons"; import axios from "axios"; const UserForm = () => { const [form] = Form.useForm(); const onFinish = (values) => { console.log("Received values of form: ", values); axios .post("http://localhost:1337/api/auth/local/register", { username: values.username, email: values.email, password: values.password, }) .then((response) => { console.log(response); alert("Registration successful!"); }) .catch((error) => { console.log(error); alert("An error occurred during registration."); }); }; return ( <Form form={form} name="register" onFinish={onFinish}> <Form.Item name="username" rules={[{ required: true, message: "Please input your username!" }]} > <Input prefix={<UserOutlined />} placeholder="Username" /> </Form.Item> <Form.Item name="email" rules={[{ type: "email", message: "Please input a valid email!" }]} > <Input prefix={<MailOutlined />} placeholder="Email" /> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: "Please input your password!" }]} > <Input.Password prefix={<LockOutlined />} placeholder="Password" /> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit"> Register </Button> </Form.Item> </Form> ); }; export default UserForm; ``` 3. Implementing email verification To implement email verification, we will use the `nodemailer` package to send emails with a unique token for each user during registration. Create a new file `sendEmail.js` in the `src` directory and add the following code: ```javascript import nodemailer from "nodemailer"; const transporter = nodemailer.createTransport({ service: "gmail", auth: { user: process.env.EMAIL, pass: process.env.EMAIL_PASSWORD, }, }); export const sendVerificationEmail = async (user) => { try { const token = crypto.randomBytes(20).toString("hex"); await axios.post("http://localhost:1337/api/auth/local/send-verification-email", { email: user.email, url: `${process.env.CLIENT_URL}/verify?token=${token}`, }); const info = await transporter.sendMail({ from: process.env.EMAIL, to: user.email, subject: "Verify your email", text: `Please click on the following link to verify your email: ${process.env.CLIENT_URL}/verify?token=${token}`, }); console.log("Email sent:", info.response); } catch (error) { console.error(error); } }; ``` 4. Building the login system Create a new file `LoginForm.js` in the `src` directory and add the following code: ```javascript import React, { useState } from "react"; import { Input, Button, Form } from "antd"; import { UserOutlined, LockOutlined } from "@ant-design/icons"; import axios from "axios"; const LoginForm = () => { const [form] = Form.useForm(); const onFinish = (values) => { console.log("Received values of form: ", values); axios .post("http://localhost:1337/api/auth/local", { identifier: values.email, password: values.password, }) .then((response) => { console.log(response); alert("Login successful!"); }) .catch((error) => { console.log(error); alert("An error occurred during login."); }); }; return ( <Form form={form} name="login" onFinish={onFinish}> <Form.Item name="email" rules={[{ required: true, message: "Please input your email!" }]} > <Input prefix={<MailOutlined />} placeholder="Email" /> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: "Please input your password!" }]} > <Input.Password prefix={<LockOutlined />} placeholder="Password" /> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit"> Login </Button> </Form.Item> </Form> ); }; export default LoginForm; ``` 5. Role-based authentication To implement role-based authentication, we will use the `jwt-simple` package to generate JWT tokens with user roles during login. Create a new file `generateToken.js` in the `src` directory and add the following code: ```javascript import jwt from "jwt-simple"; import moment from "moment"; const secret = process.env.SECRET; export const generateToken = (user) => { const expirationTime = moment().add(1, "days").unix(); const token = jwt.encode({ user, exp: expirationTime }, secret); return token; }; ``` 6. Creating a chat room with socket.io To create a real-time chat room, we will use the `socket.io` package to establish a WebSocket connection between the client and server. Create a new file `chat.js` in the `src` directory and add the following code: ```javascript import React from "react"; import { Input } from "antd"; import "antd/dist/antd.css"; import "font-awesome/css/font-awesome.min.css"; import Header from "./Header"; import Messages from "./Messages"; import List from "./List"; import socket from "socket.io-client"; function ChatRoom() { return ( <ChatContainer> <Header room="Group Chat" /> <StyledContainer> <List users={users} id={id} username={username} /> <ChatBox> <Messages messages={messages} username={username} /> <Input type="text" placeholder="Type your message" value={message} onChange={handleChange} /> <StyledButton onClick={handleClick}> <SendIcon> <i className="fa fa-paper-plane" /> </SendIcon> </StyledButton> </ChatBox> </StyledContainer> </ChatContainer> ); } export default ChatRoom; ``` 7. Implementing role-based access control (RBAC) To implement RBAC, we will use the `express-jwt` package to protect certain routes based on user roles. Create a new file `authMiddleware.js` in the `src` directory and add the following code: ```javascript import jwt from "jsonwebtoken"; import dotenv from "dotenv"; dotenv.config(); export const authMiddleware = (req, res, next) => { try { const token = req.headers.authorization.split(" ")[1]; const decodedToken = jwt.verify(token, process.env.SECRET); req.userData = decodedToken; next(); } catch (error) { res.status(401).json({ message: "Invalid token" }); } }; ``` 8. Testing and deployment To test the chat application, run the following commands in separate terminal windows: - `npm start` to start the React client - `npm run server` to start the Strapi server You can now access the chat application at http://localhost:3000. To deploy the application, you can use platforms like Heroku or Vercel. That's it! You have successfully built a chat application with role-based authentication using React and Strapi version 4.

Company
Strapi

Date published
June 28, 2022

Author(s)
Fredrick Emmanuel

Word count
4570

Hacker News points
None found.

Language
English


By Matt Makai. 2021-2024.